Использование tesseract для распознавания номерных знаков
Я разрабатываю приложение, которое может распознавать номерные знаки (ANPR). Первым шагом является извлечение лицензионных пластин из изображения. Я использую OpenCV для обнаружения пластин на основе соотношения ширина/высота, и это работает очень хорошо:
![extracting license plates]()
![extracting license plates]()
Но, как вы можете видеть, результаты OCR довольно плохие.
Я использую tesseract
в моей среде Objective C
(iOS). Это мои переменные init
при запуске движка:
// init the tesseract engine.
tesseract = new tesseract::TessBaseAPI();
int initRet=tesseract->Init([dataPath cStringUsingEncoding:NSUTF8StringEncoding], [language UTF8String]);
tesseract->SetVariable("tessedit_char_whitelist", "BCDFGHJKLMNPQRSTVWXYZ0123456789-");
tesseract->SetVariable("language_model_penalty_non_freq_dict_word", "1");
tesseract->SetVariable("language_model_penalty_non_dict_word ", "1");
tesseract->SetVariable("load_system_dawg", "0");
Как я могу улучшить результаты? Должен ли я позволить OpenCV делать больше манипуляций с изображениями? Или есть что-то, что я могу улучшить с помощью tesseract?
Ответы
Ответ 1
Две вещи полностью исправит это:
-
Удалите все, что не является текстом изображения. Вам нужно использовать некоторое резюме, чтобы найти область пластины (например, по цвету и т.д.), А затем замаскировать весь фон. Вы хотите, чтобы вход tesseract был черно-белым, где текст черный, а все остальное - белый.
-
Удалите перекос (как упоминалось выше в FrankPI). tesseract на самом деле должен работать нормально с перекосом (см. " Tesseract OCR Engine" обзор Р. Смита), но, с другой стороны, он не всегда работает, особенно если у вас есть одна строка, а не несколько абзацев. Поэтому сначала удаление косы вручную всегда хорошо, если вы можете сделать это надежно. Вероятно, вы знаете точную форму ограничивающей трапеции пластины с шага 1, поэтому это не должно быть слишком сложно. В процессе удаления перекоса вы также можете удалить перспективу: все номерные знаки (обычно) имеют один и тот же шрифт, и если вы масштабируете их до одной и той же (без перспективы) формы, формы букв будут точно такими же, что поможет распознавание текста.
Некоторые дополнительные указатели...
Не пытайтесь сначала кодировать это: сделайте очень простое распознавание (т.е. прямое, без перспективы) изображение пластины, отредактируйте его в Photoshop (или gimp) и запустите его через tesseract на командная строка. Продолжайте редактировать по-разному, пока это не сработает. Например: выберите по цвету (или наводнение выберите формы букв), заполните черным цветом, инвертируйте выделение, заполните белым, преобразуйте перспективу так, чтобы углы плиты были прямоугольником и т.д. Возьмите кучу картинок, несколько более сложных (возможно, от нечетных углы и т.д.). Сделайте это со всеми из них. Как только это полностью сработает, подумайте о том, как сделать алгоритм CV, который делает то же самое, что вы делали в фотошопе:)
P.S. Кроме того, лучше начать с изображения с более высоким разрешением, если это возможно. Похоже, что текст в вашем примере составляет около 14 пикселей. tesseract работает очень хорошо с 12-точечным текстом при 300 dpi, это около 50 пикселей в высоту, и он работает намного лучше при 600 dpi. Постарайтесь, чтобы размер вашего письма составлял не менее 50, предпочтительно 100 пикселей.
P.P.S. Вы делаете что-нибудь для train tesseract? Я думаю, что вы должны это сделать, шрифт здесь достаточно разный, чтобы быть проблемой. Вам, вероятно, также нужно что-то распознать (и не наказывать) тире, которое будет очень распространено в ваших текстах, похоже, во втором примере "T-" распознается как H.
Ответ 2
Я не знаю tesseract слишком много, но у меня есть информация об OCR. Здесь мы идем.
- В задаче OCR вы должны быть уверены, что данные вашего поезда имеют тот же шрифт, который вы пытаетесь распознать. Если вы пытаетесь распознать несколько шрифтов, убедитесь, что у вас есть эти шрифты в данных поезда, чтобы получить лучшую производительность.
- Насколько я знаю, tesseract применяет OCR несколькими способами: во-первых, вы даете изображение, в котором есть несколько букв, и пусть tesseract выполняет сегментацию. И другие, вы даете сегментированные письма в tesseract и только ожидаете, что он распознает письмо. Возможно, вы можете попытаться изменить тот, который вы используете.
- Если вы сами обучаете распознавателя, убедитесь, что у вас есть достаточно и одинаково количество каждой буквы в данных вашего поезда.
Надеюсь, что это поможет.
Ответ 3
Я работаю над iOS-приложением, если вам нужно улучшить результаты, вы должны тренировать Tesseract OCR, это улучшило 90% для меня. До начала транскрипции результаты OCR были довольно плохими.
Итак, я использовал этот gist в прошлом для обучения Tesseract ORC с использованием шрифта номерного знака.
Если вам интересно, я открывал этот проект несколько недель назад на github
Ответ 4
Вот мой пример с реальным миром, когда я тестировал OCR с моего старого измерителя мощности. Я хотел бы использовать ваш код OpenCV, чтобы OpenCV автоматически обрезал изображение, и я сделаю сценарии очистки изображений.
- Первое изображение является исходным изображением (номера счетчиков электроэнергии)
- Второе изображение - слегка очищенное изображение в GIMP, около 50% точности OCR в tesseract.
- Третье изображение полностью очищено - 100% распознанное распознавание без какой-либо подготовки!
![enter image description here]()
![enter image description here]()
![enter image description here]()
Ответ 5
Теперь лицензионная пластина легко распознается mlmodel. Я создал основную модель, вы можете найти ее здесь. Вам просто нужно разделить символы в разрешении 28 * 28 через систему видения и отправить это изображение в VNImageRequestHandler, как показано ниже -
let handler = VNImageRequestHandler(cgImage: imageUI.cgImage!, options: [:])
вы получите желаемые результаты, используя мою основную модель mlmodel. Используйте эту ссылку для лучшего пояснения, но используйте мою модель для получения лучших результатов при распознавании номерных знаков.