Как можно улучшить распознавание еденичных символов по шаблонам?
Пытаюсь сделать программку для распознавания номеров машин. Попробовал tesseract, а он жутко тормозной оказался и не сможет в реал тайме. По этому решил ручками сделать через эталонные шаблоны.
Взял каноничную картинку с алфавитом русских букв и цифр. Импортирую картинку, режу на символы, бинаризую и делаю ресайз в 5x7, храню в мапе. Теперь на этапе, когда приходит кусок картинки на которой только 1 символ, то алгоритм превращает его в такой же, как у эталонов размер и цвета и перебором всех сравнивает функцией absdiff(). На выходе получается того же размера и формата картинка с разницей. Чтобы оценить успешность, я беру функцию opencv sum(cv::Mat) и она выдаёт мне сумму всех значений пикселов, за тем я делю этот результат на количество пикселов в картинке и получаю число от 0 до 255. Чем меньше это число, тем вероятнее правильность выбора символа, который достаётся из мапы в виде string. Если вероятность не достигла установленного минимума, скажем в 100, то считается, что символ найден не был вовсе, тогда возвращается пустая строка.
Собственно, оно, вроде как, работает, но по сравнению с тессерактом улучшения в качестве распознавания я не увидел, может ухудшения есть, но мне не очень заметно. Единственно есть плюс, ради чего затевалось, это получение реал тайм скорости вместо слайд шоу.
Кто-нибудь, посоветуйте, чем можно этот алгоритм сделать более годным?
Попробовал tesseract, а он жутко тормозной оказался и не сможет в реал тайме.
Уменьшите разрешение изображения.
Задайте в настройках распознавать только те буквы что встречаются в номерах.
Отключите словари.
Перед скармливанием тессеракту почистите изображение насколько возможно (даже простой pixConvertRGBToLuminance из лептоники на удивление улучшал распознавание).
И если поставлю в символы только цифры, то на конечном результате это не отражается. Должно вроде ASCII быть цифры одни, а нет - с переводами строки в консоль выводит. Думается, что-то с локалью, но по идее если стоит "rus" и UTF8, то оно должно само там где-то правильную строку создавать, для ru_RU.UTF-8. Вот я вывожу строку OCRCHARACTERS без проблем. Ожидаю, что GetUTF8Text мне таким же образом сформирует результат.
А для вывода использовать std::wcout, в который посылать std::wstring
Правда как корректно преобразовать вашу строку в wstring не скажу.
Сам я просто использовал qt, где есть utf8 декодер в строку из коробки.
У меня линукс.
Вывод мусора я выяснил, это из-за того, что у меня три вон тех строчки были не после Init, а до. Как только вернул их так, как в первом посте, стало выводить почти нормально: в начале русская буква, потом перевод строки или, может быть, даже с пробелами. Где-то у меня была функция trim на это. Во: www.martinbroadhurst.com/how-to-trim-a-stdstring.html
Почитал ещё документацию к GetUTF8Text, а там написано, что возвращаемое значение это указатель на char, который нужно делать delete[]. RAII :)