Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > Распознование графики


Автор: former 12.4.2006, 23:14
Каким образом можно распознать объекты на рисунке (прямоугольники, элипсы и т.д.), используя при этом библиотеку похожих по форме элементов, и преобразовать их в отдельные векторные элементы.

Автор: Alexeis 13.4.2006, 09:00
former, распознование это очень непростое дело я сам этим занимаюсь, поэтому чтоб как-то помочь нужна информация о природе картинки(фотография, рисунок) , о заливке фигуры (сплошная, градиентная, произвольная), озашумленности изображения о контрасте, о глубине цвета (серая или цветная), о числе возможных фигур, могут ли фигуры иметь различные размеры и .т.д. - От этих параметров сильно зависит сложность и надежность метода распознавания.

Автор: former 13.4.2006, 17:11
Цитата

former, распознование это очень непростое дело я сам этим занимаюсь, поэтому чтоб как-то помочь нужна информация о природе картинки(фотография, рисунок) , о заливке фигуры (сплошная, градиентная, произвольная), озашумленности изображения о контрасте, о глубине цвета (серая или цветная), о числе возможных фигур, могут ли фигуры иметь различные размеры и .т.д. - От этих параметров сильно зависит сложность и надежность метода распознавания.


Картинка составлена из множества многоугольников (10-20 шт.) разных размеров и сложной формы, но с прямыми углами (не фотография, нарисована в CorelDraw или др. проге). Эти многоугольники необходимо распознать и сравнить каждый с библиотечным по подобию формы (размеры могут не соответствовать). Если соответствие не найдено, добавить в библиотеку.

По поводу заливки не знаю. Может быть её стоит делать разных цветов, что бы было проще определять тип элемента?

Пример картинки могу скинуть на мыло.

Автор: Alexeis 14.4.2006, 09:38
Цитата(former @ 13.4.2006, 16:11 Найти цитируемый пост)
Пример картинки могу скинуть на мыло.

лучше сделать ссылку чтоб все могли посмотреть...

однородная заливка не повредит, но сильно не поможет

Первое что нужно сделать - матрица размера - соответствующего размерам картинки, в ней будем устанавливать флаги пикселей проверил - не проверил.

Второе - это выделить замкнутые контуры - т.е. занести все точки черного цвета находящиеся на расстоянии 1 пикель друг от друга (цвета границы) в отдельный массив, и так для всех многоугольников. Все проверенные точки заносят в матрицу(можно значения установить в единицю например).

Следующий этап будет распозновании линиий. Попробуйте реализовать вначале первые два.

ps если не куда повесить картинку - пришлите я сам сделаю ссылку.

Автор: former 14.4.2006, 21:48
Картинку отправил на E-mail.

Цитата

Первое что нужно сделать - матрица размера - соответствующего размерам картинки, в ней будем устанавливать флаги пикселей проверил - не проверил.


alexei-s1, я работал только спростейшей графикой, а с пиксельной ещё
не доводилось. Как это можно реализовать?

Цитата

Второе - это выделить замкнутые контуры - т.е. занести все точки черного цвета находящиеся на расстоянии 1 пикель друг от друга (цвета границы) в отдельный массив, и так для всех многоугольников. Все проверенные точки заносят в матрицу(можно значения установить в единицю например).


А если тощина линии более одного пикселя?

Автор: former 14.4.2006, 22:32
Вообще, какие требования далжны быть к изображению?

Автор: Alexeis 17.4.2006, 09:44
Цитата(former @  14.4.2006,  20:48 Найти цитируемый пост)
alexei-s1, я работал только спростейшей графикой, а с пиксельной ещё
не доводилось. Как это можно реализовать?


Я имел ввиду 
Код

var
  m : array[0..MyImageHeight - 1, 0..MyImageWidth - 1] of Byte;
 

Автор: Alexeis 17.4.2006, 10:44
Цитата(former @  14.4.2006,  21:32 Найти цитируемый пост)
Вообще, какие требования далжны быть к изображению?


требования как правило предъявляют не к изображению, а к алгоритму распознавания.

Вообще нельзя использовать Jpeg для хранения изображения.

Задача во многом упростится если делать такие чертежи в векторном редакторе, типа visio или АutoCad, тогда даже не придется распозновать линнии, так как они уже будут заданы в файле векторного формата.

Вообще, очень рекомендую перейти от растровой к векторной графике, тем более что круг задач как раз к этому распологает.
 smile  

-----------------------------------------------------------------------------------------
По просьбе автора я выкладывою пример изображения
http://alexei-s1.narod.ru/01.jpg 

Автор: former 17.4.2006, 21:58
А я и использую bmp, просто отправил в jpg.

Код

Я имел ввиду 

var
  m : array[0..MyImageHeight - 1, 0..MyImageWidth - 1] of Byte;


Я так понял, что создаётся динамический массив, который заполняется элементами изображения, т.е. цветом пикселя, так? Как тогда осуществлять проверку цвета пикселя (чёрный/белый), и как свормировать из этого массива элементы изображения, т.е. разбить изображение на отдельные элементы?  Получается, что после этого необходимо попиксельно сравнить элемент из библиотеки? smile 
 
Код

Задача во многом упростится если делать такие чертежи в векторном редакторе, типа visio или АutoCad, тогда даже не придется распозновать линнии, так как они уже будут заданы в файле векторного формата.


Но тогда надо знать сам формат и уметь считать его из файла.

 

Автор: Alexeis 18.4.2006, 09:50
Цитата(former @  17.4.2006,  20:58 Найти цитируемый пост)
Но тогда надо знать сам формат и уметь считать его из файла.


форматы *.emf, и *.wmf , являются общепризнаными и информация об их формате у меня имеется, найти инфу о формате autocada - вообще не проблема.

Дело в том что распознование битмапа будет всегда производися с погрешностью, а первый этап поставленной задачи, фактически и будет превращение растра в векторное представление Т.е будет производится двойная работа. Вначале редактор линии превратит в точки затем, наша программа буден по точкам востанавливать линнии - это оправдано когда изображения даются от изначально растрового источника (фотоаппарата, сканера и т.д.). Чертежи вообще принято хранить в векторном формате, тогда их легче редактировать, масштабировать и поворачивать. По меньшей мере будет нелогично хранить битмап если можно *.wmf.

Так ради справки покажу как работать с битмапом.
Объявляются такие структуры
Код

  TRGB = packed Record
           b,g,r : byte;
         end;

  Line = array[0..32768] of TRGB;
  pLine = ^Line;
  
var
  mask1 : array of pLine;


Конвертируем растр из DDB в DIB

Код

  image1.Picture.Bitmap.PixelFormat := pf24bit;


Устанавливаем размеры битмапа(если не загружен)
Код

  image1.Picture.Bitmap.Width  := image1.ClientWidth;
  image1.Picture.Bitmap.Height := image1.ClientHeight;


Выделяем память под массив указателей
Код

  SetLength(mask1, Image1.Picture.Bitmap.Height);


Заполняем масив указателей реальными указателями адресов строк изображения
Код

  For i := 0 to Image1.Picture.Bitmap.Height - 1
  do
    mask1[i] := Image1.Picture.Bitmap.ScanLine[i];


закрашиваем первый пиксель например красным цветом
Код

       mask1[0,0].b := 0;
       mask1[0,0].g := 0;
       mask1[0,0].r := 255;


или читаем (color1 := RGB(mask1[0,0].r, mask1[0,0].g, mask1[0,0].b))
 

Автор: former 18.4.2006, 17:29
alexeis1, спасибо за справку по битмапу. 

Цитата

Дело в том что распознование битмапа будет всегда производися с погрешностью, а первый этап поставленной задачи, фактически и будет превращение растра в векторное представление Т.е будет производится двойная работа.


Из-за чего будет погрешность?

Цитата

...это оправдано когда изображения даются от изначально растрового источника (фотоаппарата, сканера и т.д.)


Дело в том, что изображение может быть получено из сканера.

Непонятно, зачем нам первый пиксель закрашивать красным цветом? 

Дальше, на сколько я понимаю, для выделения объектов из рисунка необходимо пробежаться по всему массиву с проверкой цвета соседних элементов? Хотя если, например два прямоугольника имеют общую границу, то это будет сделать трудно. 

Автор: former 18.4.2006, 20:02
Создал, для начала, картинку (w-200 п, h-100 п) с незакрашенным прямоугольником, загрузил её в Image и попытылся прочитать. Так же создал таблицу StringGrid c размером ячейки (3х3п) и колличеством ячеек, как и у картинки. Следующим шагом попытался заакрасить ячейки таким же цветом как на картинки, т.е. перенести попиксельно картику в таблицу, но:

Цитата

или читаем (color1 := RGB(mask1[0,0].r, mask1[0,0].g, mask1[0,0].b))


а 

Цитата

mask1[i] := Image1.Picture.Bitmap.ScanLine[i];


  smile  

Автор: Alexeis 20.4.2006, 14:05
Цитата(former @  18.4.2006,  16:29 Найти цитируемый пост)
Непонятно, зачем нам первый пиксель закрашивать красным цветом?

Это для примера пусть не первый, а любой, и цвет можно выбирать любой smile 

Цитата(former @  18.4.2006,  16:29 Найти цитируемый пост)
Дело в том, что изображение может быть получено из сканера.


Если так, то лучше воспользоваться готовой программой для перевода из растровой графики в векторную графику, на torry.net я скачивал подобную.
Очень советую использовать чужую програму, потому что операция перевода из картинки в линии достаточно сложная.

Добавлено @ 14:06 
http://www.torry.net/vcl/charts/cad/r2vto285.zip 

Автор: former 20.4.2006, 16:42
Дело в том, что я хочу написать экспертную систему, которая сканируя рисунок, выделяя в нём элементы и сверяя их с библиотечными, выдавала пользователю информацию об устройстве, изображённом на рисунке, а затем позволяла бы выолнить его проектирование и моделирование.

Не хочу зависеть от Autocad-а, поэтому dwg отпадает, а вот использовать wmf или emf похоже придётся. 


alexeis1, не могли бы вы привести пример чтения объектов из wmf или emf и поделиться его описанием? 

Автор: Alexeis 21.4.2006, 10:48
Вот ссылочки
http://www.wotsit.org/search.asp?page=10&s=graphics
http://wvware.sourceforge.net/libwmf.html
http://www.fileformat.info/format/wmf/

а вообще в делфи есть класс TMetaFile но он не самый удачный я думаю на torry.net есть лучше компоненты 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)