Как стать автором
Обновить

Комментарии 17

Ваш способ не учитывает погрешности распознавания. Будь ноль чуть поуже или лишняя точка у двойки внизу — и все, ошибка. Для таких простых случаев имхо стоит использовать нейронные сети.
Вы правы, при преобразовании в черно-белое изображение часто имелись расхождения с шаблоном, что давало сбои в распознавании. Плюс к этому, если число не целое, десятичный разделитель создавал проблемы. Этот метод, безусловно, не является надежным, и применим только к узкому типу задач.
С другой стороны, если шаблоны всегда соответствуют исходному изображению, этот метод один из самых быстрых, возможно, даже самый быстрый. Ведь что может быть проще, чем проверить 4 координаты?
Спасибо за критику.
Наверное, реализовать их в дельфи было более трудной задачей, если уж на то пошло, то автор мог бы использовать готовую большую библиотеку ocr. Но решение, конечно, очень частное.
Вам просто очень повезло, что на ваших конкретных входных данных такие четыре точки нашлись.
Не нашлось бы четыре — взяли бы пять или шесть — столько бы точно нашлось.
Проблема в другом — это действительно оооочень узконаправленное распознавание. Например, оно подходит, чтобы чиселки с формочки в винде вытаскивать. Когда знаешь, что один и тот же шрифт (причём моноширинный), и собираешься использовать только для себя только здесь.
Перцептрон Розенблатта ещё в середине прошлого века неплохо решал эту задачу
По своему опыту скажу — распознавать по шаблонам очень легко, но только до тех пор, пока имеем равномерный фон, заранее известного цвета.

Вот решить задачку для разноцветных и неравномерных фонов уже гораздо интереснее.
Условие задачи никто не прочитал: Быстро и точно из прямоугольника 70 на 10.
Задача решена.
Ошибонька :)

Таким образом, двигаясь слева направо сверху вниз получаем последовательность для каждой цифры:
0: '0011100011011011000111100011110001111000111100011110001111101100111100'
Просто мне лень было переделывать скриншоты. Последовательность взята из шаблона слева, а в статье использую шаблон справа. В данном случае 14-ая точка не является значащей, поэтому решил не исправлять.
Подсказка, как сделать правильно:
1. Даунсайзите выделенную цифру до размеров 5х3 или 6х4 пикселя, 256 оттенков серого, максимальный контраст (то есть полностью черные точки имеют яркость 0, полностью белые 255).
2. Заранее готовите набор эталонов (10 цифр из шрифта) в таком же качестве.
3. Далее каждый из 10 эталонов попиксельно сравниваете с выделенной цифрой и вычисляете ошибку. Ошибка равна сумме квадратов разностей пикселей (E = (Sum(i,j) { ((a[i,j]-b[i,j])^2)/65536 }) / (i*j) ). Если для какой-то эталонной цифры E<0.1 (примерно) — всё, поздравляю, распознали успешно. Если для всех больше 0.25 — значит перед вами не цифра.

Для оптических изображений это называется алгоритмом максимального правдоподобия, и с точки зрения статистики доказано, что это наиболее точный из любых возможных алгоритмов. Единственное — он очень не любит повороты.
Да, кстати, если E>0.9, то перед нами белая цифра на черном фоне.
ради этого комментария автору стоило писать статью :)
Этот способ только кажется простым, «Перебором нашел следующие точки» — перебор в уме или программой?
В любом случае, значительно проще извлечь сам набор цифр и для распознавания выбирать ту, среднеквадратичное отклонение координат точек для которой наименьшее. Будет немного медленнее работать, но более универсально.
7 на 10 пикселей все же, наверное
Такой подход годится только для идеальных изображений (синтетических). В реальных изображениях всегда присутствует шум, который будет давать случайные точки в произвольных местах. Это приведет к существенному снижению точности распознавания вашего алгоритмы.
Плюс наличие геометрических искажений, неидеальность объектива и т.п. — это тоже внесет свой вклад.
Выше chainik описал один из вариантов достаточно надежного и простого распознавания.
Вот похожее решение. Но устойчивее к искажениям.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории