Alphabet

                Раздел содержит  список используемых в системе алфавитов.

AlphabetTree

                Если выбрать алфавит в дереве, то появится Object Inspector, в котором можно увидеть и отредактировать параметры алфавита.

AlphabetTree

                Здесь для редактирования доступны  свойства:

  • Name — имя алфавита, по которому к нему можно обращаться из кода программы.
  • mainсolor — цвет из раздела Colors, определяет свойства фильтра наложенного на изображение. А именно цвет текста, который мы распознаем. Например, если на изображении есть буквы красного цвета, то мы создаем в разделе Colors цвет Red и выбираем его в поле maincolor в настройках алфавита. В случае если maincolor = ‘None’ то распознавание будет вестись в цветонезависимом режиме.
  • StrDiv — разделитель который будет вставляться между распознанными строками в итоговой строке (которая возвращается в результате распознавания)
  • qtyBetweenSymb — количество столбцов шириной в пиксель между соседними символами на анализируемом изображении. Межбуквенное расстояние, промежутки больше чем указаны в этом свойстве будут считаться промежутками между словами.
  • EmptyColSym — количество столбцов шириной в пиксель, которые будут проигнорированы. Т.е. если свойство = 1, то объекты на изображении между которыми промежуток шириной в один пиксель будут считаться одним объектом, если же свойство = 0, то такие объекты будут считаться разными символами.
  • WordsDiv — символ который будет вставлен между словами в распознанной строке (по умолчанию пробел).
  • Teach — свойство которое определяет будет ли проводится обучение в процессе работы или нет. Если свойство равно true, то если программа в процессе работы не сумеет распознать объект, она добавит его шаблон в алфавит с незаполненным идентификатором. Процесс добавления в базу данных активируется при закрытии окна программы в режиме Runtime (т.е. когда нажимаем на крестик в верхнем правом углу, если программу закрыть через диспетчер задач, то новые шаблоны в базу записаны не будут).
  • k — коэффициент совпадения шаблона и распознаваемого символа при котором символ будет считаться распознанным.
  • qtyBeetwenStrings — количество пикселей между строками, т.е. если в символах есть разрывы по вертикали, и они меньше этого значения (в пикселях), то такие разрывы будут проигнорированы и объект внутри которого они были обнаружены будет распознан как единый символ.

                 На следующем уровне иерархии  после названия алфавита содержится список шаблонов алфавита, т.е. непосредственно шаблоны распознаваемых символов. Добавление новых шаблонов вручную не предусмотрено. Вместо этого необходимо создать код программы, которая будет распознавать некий текст, и после ее запуска все незнакомые буквы будут помещены в этот список (свойство teach алфавита необходимо установить для этого в true), вам лишь останется задать шаблону текстовое соответствие, заполнив свойство Name в Object Inspector для каждого шаблона.

Функции для распознавания текста:

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

Function TextRecognizeInCoord (Left,Top,Right,Bottom :Cardinal; AlphabetName:string): string; — распознает текст в произвольных координатах

                Рассмотрим пример:

                Откроем Paint и нарисуем в нем простую картинку:

AlphabetTree

                В желтом прямоугольнике введем красный текст «Hello World».  Наша задача:

1) Найти желтый прямоугольник

2) Распознать красный цвет внутри прямоугольника

 

                Через Launcher  создадим новую базу данных. Зайдем в нее в режиме конструктора. Сделаем так чтобы окно Paint с нашей картинкой было под окном конструктора, нажимаем в конструкторе кнопку ScreenShot, появится TV со снимком нарисованной картинки. Чтобы продолжить нам необходимо добавить в раздел Colors два цвета желтый и красный. Добавляем красный, как было описано выше. Галочки Red > Blue и Red > Green необходимо установить. В Result color  компоненту R установить равной 255. В поле имя пишем Red. Нажмем Save и цвет появится в дереве объектов. Нажмем Refresh TV и на сделанном нами скриншоте увидим результат.

redsq

…Желтый прямоугольник тоже стал красным, что-то пошло не так. Жмем на кнопку Normal и начинаем разбираться. На экране появился исходный снимок, наводим курсор на прямоугольник и смотрим внизу справа экрана параметры RGB у меня там написано 255 242 0, что вполне укладывается в те параметры фильтра, которые мы задали, поэтому справедливо, что и желтый прямоугольник стал красным. Для того чтобы исправить ситуацию мы могли бы сократить диапазон по компоненте B  до нуля, но полагаю, что для красного цвета компонента B > 0 также возможна. Поэтому мы обратим внимание на параметр Almost equal delta, в нем по умолчанию стоит 10, но  255 — 242 = 13. Необходимо иметь ввиду, что если галочки из группы almost equal установлены в значение истина, то проверяется равенство между соответствующими компонентами. Но если эти галочки не установлены, как у нас, то проверяется неравенство, т.е. чтобы пройти фильтр компоненты должны быть неравны друг другу, а т.к. 13 > 10 то и получается, что для нашего желтого прямоугольника Красная компонента не равна зеленой. А это значит что прямоугольник подходит под условия фильтра. Поэтому увеличим значение реквизита Almost equal delta до 20. Тогда 13 < 20  и считается что для данной картинки R=G, что соответствует значению галочки  Red almost equal Green равному истине, но т.к.  эта галочка у нас не установлена, то  под наш фильтр такой цвет не подходит, и когда мы обновим изображение кнопкой Refresh TV, то увидим уже только

helloworld

                На изображении есть и другие красные участки, но в данном случае нас интересует только прямоугольник и то, что находится внутри него. У меня настройка красного выглядит так:

 

   red

             Итак, мы добавили красный цвет, аналогично добавляем желтый. Для желтого цвета R =G, как мы уже выяснили в примере с красным цветом, разница между R и G у нас 13, а потому Almost equal delta делаем 20. У меня настройки желтого выглядят следующим образом:

yellow

 

                Остальные цвета вы можете подбирать аналогично тому, как я делал это выше для красного цвета. Поэкспериментируйте с настройками и скоро вы многое узнаете о цветах в формате RGB. В основных цветах (красный, зеленый, синий) компонента этого цвета всегда значительно больше остальных двух. В цветах, получаемых при смешивании основных цветов обычно 2 из трех компонент примерно равны между собой и больше чем третья (мы рассмотрели это для розового и желтого цветов). Лично я разобрался в этих хитросплетениях именно с помощью этой формы никакой спец. литературы я не читал.

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

                Создание цветов выглядит трудоемким занятием, но на самом деле мне хватало 7-8 цветов на все случаи жизни для одной игры. Не рекомендую создавать цвета с очень широкими диапазонами, т.к. в этом случае вы рискуете тем, что в них будет попадать, в том числе, и не совсем то,  что вы ожидали. Перед тем как создавать цвета, я изучаю RGB (как мы делали это для красного цвета) объектов которые я хочу найти и, исходя из этих цифр, создаю фильтр. Слишком узкие диапазоны тоже создавать не стоит, т.к. в реальном приложении цвета в объекте могут колебаться в некотором диапазоне.

                После того как мы добавили цвета, нажмем кнопку ColMap и кликнем в пункт Colors в дереве объектов, для того чтобы увидеть результат наших стараний. У меня это выглядит так, как показано на картинке ниже. На изображении есть и другие картинки, в которых есть наши цвета, но они нас не интересуют.

 rect2

 

                Наконец  мы настроили цвета и теперь нам нужно сделать шаблон прямоугольника, т.к. мы его будем искать, и сделать алфавит, т.к. его мы будем распознавать.

                Для того чтобы сделать шаблон прямоугольника в разделе Colors кликаем на пункте Yellow, и при этом у нас должна быть нажата кнопка ColMap. Получаем монохромное изображение.

Monrect

                У меня внутри прямоугольника видны некоторые артефакты, это фрагменты надписи которые попали в желтый фильтр. В принципе, т.к. их немного, то это не критично, и можно все оставить и так, существенного влияния на результаты поиска это не окажет. Но если все же вам не лень, то можно несколько оптимизировать шаблон, удалив артефакты, а также и центральные части линий, т.к. в принципе в данном случае они ничего нам не дают, кроме некоторого увеличения времени поиска. Нажмем кнопку Delete rect  и удалим лишнее.

Жмем кнопку select и выделяем наш прямоугольник.

rect3

жмем на правую кнопку мыши внутри прямоугольника, появляется окно

ins2

                В нем поле Main color  уже имеет значение Yellow т.к. мы делали шаблон с выбранным желтым цветом в режиме ColMap и нам остается внести только имя шаблона, я назову его Rect. Жмем Input  и видим результат наших действий в разделе Template.

                Теперь добавим алфавит. Назовем его Hello. Жмем правой кнопкой мыши на пункте дерева объектов Alphabet и выбираем пункт добавить алфавит.  Заполняем имя, а MainColor необходимо указать Red. Если где-то ошиблись при вводе или необходимо поменять настройки, то  нажав на алфавит, или шаблон в дереве объектов вы увидите все эти свойства в инспекторе объектов и там же вы можете их изменить. Удалить любой элемент дерева можно, кликнув правой кнопкой мыши на нем, и выбрав соответствующий пункт в выпадающем меню.

                И наконец, приступим к программированию! Добавляем на форму кнопку, как мы это уже делали ранее (дизайнер форм открывается через меню окна). Добавляем ей событие OnClick. В процедуре пишем Rect, или перетаскиваем его из дерева объектов. Ставим точку из выпадающего меню выбираем RecognizeText, надпись AlphabetName: string заменяем на ‘Hello’

                Добавим еще сообщение, которое будет выдавать нам распознанный текст. Если текст распознан, то он хранится в свойстве Text шаблона. Итоговый текст должен выглядеть так:

text4

                Конструкция Rect.RecognizeText сначала ищет объект Rect, а потом на найденном участке изображения пытается распознать текст, используя шаблоны букв из коллекции Hello, причем в расчет будут приниматься только красные буквы(или иные объекты красного цвета). Для текущего алгоритма распознавания критично, чтобы текст был четко структурирован, в нем должны быть строки (т.е. между строками должно быть пространство), между буквами должны быть пробелы, между словами большие пробелы, иначе распознавание будет произведено неверно.

                А тем временем наша программа готова к запуску, сохраняем, запускаем. Делаем так, чтобы на фоне был виден наш прямоугольник, который мы нарисовали в Paint и жмем кнопку Button1 на форме. И получаем пустое сообщение, т.к. в нашем алфавите нет шаблонов символов. Теперь идем в конструктор, жмем правой кнопкой мыши на пункте меню Alphabet и выбираем обновить, в дереве в разделе Hello должны появится новые пункты. У всех у них нет никакого значения в дереве. Необходимо по очереди выбирать эти пункты и проставлять символы соответствующие картинке. Картинку можно увидеть в нижней части дерева объектов, она появляется, если щелкнуть на шаблоне левой кнопкой мыши. Если по этой картинке дважды щелкнуть левой кнопкой мыши, то она будет выведена на TV, где ее можно масштабировать либо отредактировать и вставить обратно. Также возможно сохранить ее в виде файла *.bmp на жесткий диск, через меню Файл. После того как все названия в шаблонах заполнены, приложение можно перекомпилировать и запустить снова. Теперь в сообщении мы должны увидеть ‘Hello world’ при условии, что шаблоны заполнены правильно.

 

Bot Development Engine