Перейти к содержимому
Compvision.ru
svoyak

Подготовка сэмплов для OCR(вопросы)

Recommended Posts

Здравствуйте, добралось и до меня распознавание тескста.. Много прочитал коечто сделал ну и соотвественно натолкнулся на некоторые трудности.:-)Я их перечислю ниже, если не тяжело то дайте советы
по преодолению..:-)
Общий алгоритм таков: 1. Повышаю контраст. 2. Перевожу в градации серого. 3.Делаю бинаризацию.4 Получаю контуры.5 - сортирую их по площади выбираю больше определнного числа(это буквы).Далее хочу настрогать большое количесвто разных и скормить
нейросети FANN. До скармливания наборов сети еще не дошел, т.к. хотел получить максимально вменяемый набор символов.
Итак о трудностях:
1. При бинаризации(обычная OTSU) очень часто получаю прерывистую змейку вместо линии, очевидно что промежуточный серый и около него отбрасывается, а хотелось бы наоборот чтоб он считался как черный,
чтоб линии были без разрывов. Мне кажется тогда контуры будут получше находится. Из чтения форума выяснил что стоит попробовать адаптивную бинаризацию, так ли это? Может что нить еще?
2. Самая большая проблема - слипшиеся символы.. Пока решение не придумал, как их разделять. Есть метод ConnectedComponents, что делает я понял, но как это натянуть на разделение символов - не понял.
Может он и не для этого совсем? Подскажите плз. Ну и вообще как бы решить задачу разделения. Единственное, что пока придумал - бежать окном и смотреть степень похожести с последующим вырезанием.
Но я вот не знаю скорость работы нейросети, мне кажется она не справится(реал тайм не обязателен, но время меряется единицами минут). Ну и сопуствующий вопрос - может tesseract прикрутить для
разделения? Почему не хочу полностью использовать tesseract - шрифты сильно разные, поэтому думаю не справится - отсюда выбрал нейросеть. Да вот еще не знаю стоит ли гдето в процессе вставить
скелетизацию, так как плохо понимаю ее влияние, стоитл ли? и где?:-) Вообщем както так..Спасибо всем за советы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Попробуйте tesseract :) 

Обучение tesseract-а.

По поводу бинаризации, у меня вот это хорошо работало: http://stackoverflow.com/questions/22122309/opencv-adaptive-threshold-ocr/22127181#22127181 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

попробовать tesseract - для всего или для какой-то конкретной стадии?

Про бинаризацию: вот такие у меня результаты: оригинал, обычная и адаптивная на обычной потом ессно контуры находит лучше, может это нормально и я хочу невозможного?    Это код:              

                        CvInvoke.AdaptiveThreshold(m, bin_m, 255, AdaptiveThresholdType.MeanC, ThresholdType.BinaryInv, 3, 0);

                        CvInvoke.Threshold(m, bin_m, 254, 255, ThresholdType.BinaryInv | ThresholdType.Otsu);


   

 

 

я_orig.jpgя_otsu.jpgя_adap.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Он вполне себе нормально интегрируется с OpenCV.


ЗЫ: На такой шрифт лучше учить отдельно. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Дело в том что шрифты разные могут быть, я конечно попробую tesseract, но еще мне хотелось сделать наконец что-нить с нейросетью:-)) помоему это неплохой вариант, ну..вскрытие покажет как говорится.. Скажите плз, а как лучше избавится от шума в виде мелких точек перед бинаризацией? Я так понимаю сейчас я от него избавляюсь большими порогами при бинаризации - за это как раз и плачу потом разорванными контурами букв.. Если б убрать мелочь до бинаризации - возможно ее получилось бы провести более лояльно?? Спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

erode + dilate после бинаризации

Уберет все мелкое в зависимости от параметров.

 

До бинаризации можно попробовать сглаживание (медианный фильтр, анизотропная фильтрация, ,, в этом духе)

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Так отлично, спасибо..есть направление для движения.. а по разделению символов есть какие-то умные пути?? Я понимаю что перебор окном возможно и пойдет, но как то это слегка топорно.. И если не тяжело скажите, зачем применяется ConnectedComponents даже если не сюда все равно интересно:-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

По разделению не скажу, использовал tesseract.

Можно окном сверточной сетки гонять и смотреть отклики а затем по словарю искать, но сам не делал.

ConnectedComponents просто маркирует отдельные связанные куски пикселей.

Например если два круга отдельно нарисовано, то результатом будет изображение, на котором все пиксели одного круга будут иметь значение 1, а другого 2.  Если с пересечением, то вся область будет иметь значения 1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
On 22.07.2016 at 5:43 PM, svoyak said:

Так отлично, спасибо..есть направление для движения.. а по разделению символов есть какие-то умные пути?? Я понимаю что перебор окном возможно и пойдет, но как то это слегка топорно.. И если не тяжело скажите, зачем применяется ConnectedComponents даже если не сюда все равно интересно:-)

Разделение часто делают по гистограмме. Есть у нас изображение шириной W строки с текстом. Тогда заводим массив размером W, каждый элемент которого есть сумма пикселей изображения по столбцам. Сглаживаем, ищем минимумы - они примерно будут соответствовать границам символов.

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я слабо представляю, чем может помочь скелетизация при распознавании символов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Подключил я Fann, сделал нейросеть но вот только какая странность, не дает она правильных результатов. У меня был проект для примера там делалась сеть (600,200,52)(картинка 25х24) - 4000 картинок символов ей скармливалось для тренировки - так вот этот проект я у себя построил, пересоздал сеть и проверил - все работает, возвращает массив в котором наибольшая вероятность соответствует индексу правильного элемента. Когда я в этот механизм загоняю свои данные: (8000, 2500,16)(картинка 80x100), 16 - я взял для тестов не весь алфавит. результат вообще непонятный почти везде стоят 1(100%), вероятность искомого отличается от 1,но ессно она меньше. Оговорюсь, что я скормил на обучение всего 30 картинок, но потом для теста я дал одну из них. Я считал, что сеть должна ее решить верно, так как картинка была в обучающей выборке, а сеть выдала какую-то непонятку. Собсно вопрос, где я неправильно думаю, может 8000 - это сильно много для входного слоя и мне нужно уменьшить размер картинок символов? может сеть не должна находить точно те данные, которые были в обучающей выборке если выборка такая маленькая? Спасибо

Кстати, можно ли как-то контролировать успешность процесса обучения?? При вызове net.TrainOnFile(openFileDialog1.FileName, 100, 10, (float)0.0001); я так понял в параметрах можно задать кол-во итераций(100) , и нужную погрешность(0ю0001), но что если за это кол-во итераций погрешность не будет достигнута? можно также получать колбэк после итерации, но там нет текущих параметров погрешности.. Когда я запускал один из первых разов обучение, вроде бы мне в консоль выводилась информация о текущей итерации и достигнутой погрешности(хотя я колбэк тогда еще не вешал ), это похоже сам FANN выводил чтоли.. но вот беда, кудато эта фишка пропала.. и теперь я не вижу процесса.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Обучите в матлабе, и сдерите оттуда обученную сеть, делал так в одном проекте, очень удобно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хм.. я так понимаю совместимость там подразумевается?? мне почему-то кажется что проблема не в инструменте, а в данных или их количестве.. как я уже сказал, тестовый пример работает отлично, притом что я перестроил его сеть...сейчас запустил 10000 итераций - закончит посмотрю на изменения..

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да я к тому, что в матлабе быстрее диагностику проводить, посмотреть учится/не учится, какая точность, подстроить архитектуру сети, да и алгоритмы в матлабе весьма неплохие. 

Все можно делать через GUI при помощи: nprtool .  

А так то веса и в Африке веса, прямой ход - пара матричных операций в конечной программе сделать несложно.

 

Часто еще ошибку с предобработкой входных данных допускают.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

При использовании нормирования, учится быстрее и стабильность лучше. 

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

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

Использовались чередующиеся 3 канала RGB, использовать чередующиеся 3 канала RGB в обоих случаях и в том же самом порядке и т.д.

 

UPD: 

Вообще я делал простенький пример на эту тему. Здесл лежит 

см. предпоследний пост. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Так,c сетью я разобрался..точней с результатами ее работы..как всегда ошибка в днк:-))(моём), я неправильно тренировочный файл делал, причем совсем немного, но фатально.. Есть вопрос еще вот такой... есть два типа шрифтов как их привести к чему-то общему, мне кажется если это сделать, то нейросети будет легче обучаться..

И еще, можно ли с помощью opencv сделать выделение как в фотошопе эффект "волшебная палочка"? В приложении типы шрифтов.

121143.bmp

125724.bmp

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Касательно "волшебной палочки" посмотрите floodFill, там есть режим маски, или поиск контуров  с флагом искать внешний (CV_EXTERNAL или как то так. ).

 

Кстати, можно еще сделать dilate + erode, это заполнит пустоты внутри штриха.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да,dilate + | erode тут поможет как раз линии становятся толстыми и пустоты внутри в процентном соотношении уменьшаются.. Вопрос в том как это будет влиять на изначально полностью черный шрифт.. или надо уметь отличать белый шрифт с черным контуром от просто черных букв, чтоб применять только к первым..

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А зачем? C черными такая операция ничего не должна сделать, ну может самую малость поменяет контур.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Подскажите плз, вот есть такое понятие как BlobDetection, вроде бы я понял что оно позволяет выделить области одинакового цвета. Пользовался ктонить этим?? Я посмотрел несколько примеров, но там народ все равно перед пользованием CvBlobDetector перегоняет картинку в Gray, получается этот блобдетектор по оттенкам серого детектит? может у кого нить есть кусочек кода с ним? у меня иногда буквы идут разного цвета и отделить их по цвету от фона и друг от друга - было бы самое оно.Спасибо. пример во вложении

blobs.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вот тут посмотрте: https://github.com/OpenCVBlobsLib/opencvblobslib там есть примеры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пересмотрел я много примеров по BlobDetection, к сожалению на мой взгляд они мне немного не подходят или я их не до конца понимаю. Все они вроде бы бинаризируют изображение перед детекцией, и получается, что цветовые различия теряются.. Т.е. если в указанном мною выше примере буквы будут также иметь разный цвет, но будут соединены  - то blobdetection выдаст мне один единственный блоб с двумя буквами вместе, хотя в реале у каждой буквы свой цвет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ооо..гугленье привело к тому, что я просто неправильно называл то, что мне нужно..правильно: opencv color segmentation, пошел читать дальше..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×