svoyak 0 Report post Posted July 22, 2016 Здравствуйте, добралось и до меня распознавание тескста.. Много прочитал коечто сделал ну и соотвественно натолкнулся на некоторые трудности.:-)Я их перечислю ниже, если не тяжело то дайте советы по преодолению..:-) Общий алгоритм таков: 1. Повышаю контраст. 2. Перевожу в градации серого. 3.Делаю бинаризацию.4 Получаю контуры.5 - сортирую их по площади выбираю больше определнного числа(это буквы).Далее хочу настрогать большое количесвто разных и скормить нейросети FANN. До скармливания наборов сети еще не дошел, т.к. хотел получить максимально вменяемый набор символов. Итак о трудностях: 1. При бинаризации(обычная OTSU) очень часто получаю прерывистую змейку вместо линии, очевидно что промежуточный серый и около него отбрасывается, а хотелось бы наоборот чтоб он считался как черный, чтоб линии были без разрывов. Мне кажется тогда контуры будут получше находится. Из чтения форума выяснил что стоит попробовать адаптивную бинаризацию, так ли это? Может что нить еще? 2. Самая большая проблема - слипшиеся символы.. Пока решение не придумал, как их разделять. Есть метод ConnectedComponents, что делает я понял, но как это натянуть на разделение символов - не понял. Может он и не для этого совсем? Подскажите плз. Ну и вообще как бы решить задачу разделения. Единственное, что пока придумал - бежать окном и смотреть степень похожести с последующим вырезанием. Но я вот не знаю скорость работы нейросети, мне кажется она не справится(реал тайм не обязателен, но время меряется единицами минут). Ну и сопуствующий вопрос - может tesseract прикрутить для разделения? Почему не хочу полностью использовать tesseract - шрифты сильно разные, поэтому думаю не справится - отсюда выбрал нейросеть. Да вот еще не знаю стоит ли гдето в процессе вставить скелетизацию, так как плохо понимаю ее влияние, стоитл ли? и где?:-) Вообщем както так..Спасибо всем за советы. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 22, 2016 Попробуйте tesseract Обучение tesseract-а. По поводу бинаризации, у меня вот это хорошо работало: http://stackoverflow.com/questions/22122309/opencv-adaptive-threshold-ocr/22127181#22127181 Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 22, 2016 попробовать tesseract - для всего или для какой-то конкретной стадии? Про бинаризацию: вот такие у меня результаты: оригинал, обычная и адаптивная на обычной потом ессно контуры находит лучше, может это нормально и я хочу невозможного? Это код: CvInvoke.AdaptiveThreshold(m, bin_m, 255, AdaptiveThresholdType.MeanC, ThresholdType.BinaryInv, 3, 0); CvInvoke.Threshold(m, bin_m, 254, 255, ThresholdType.BinaryInv | ThresholdType.Otsu); Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 22, 2016 Tesseract для всего. Скармливаете бинаризированное изображение, получаете текст. Он вполне себе нормально интегрируется с OpenCV. ЗЫ: На такой шрифт лучше учить отдельно. Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 22, 2016 Дело в том что шрифты разные могут быть, я конечно попробую tesseract, но еще мне хотелось сделать наконец что-нить с нейросетью:-)) помоему это неплохой вариант, ну..вскрытие покажет как говорится.. Скажите плз, а как лучше избавится от шума в виде мелких точек перед бинаризацией? Я так понимаю сейчас я от него избавляюсь большими порогами при бинаризации - за это как раз и плачу потом разорванными контурами букв.. Если б убрать мелочь до бинаризации - возможно ее получилось бы провести более лояльно?? Спасибо Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 22, 2016 erode + dilate после бинаризации Уберет все мелкое в зависимости от параметров. До бинаризации можно попробовать сглаживание (медианный фильтр, анизотропная фильтрация, ,, в этом духе) ЗЫ: если использовать нейронку, то с шумом она и сама в силах разобраться, главное при обучении побольше данных скормить. Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 22, 2016 Так отлично, спасибо..есть направление для движения.. а по разделению символов есть какие-то умные пути?? Я понимаю что перебор окном возможно и пойдет, но как то это слегка топорно.. И если не тяжело скажите, зачем применяется ConnectedComponents даже если не сюда все равно интересно:-) Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 22, 2016 По разделению не скажу, использовал tesseract. Можно окном сверточной сетки гонять и смотреть отклики а затем по словарю искать, но сам не делал. ConnectedComponents просто маркирует отдельные связанные куски пикселей. Например если два круга отдельно нарисовано, то результатом будет изображение, на котором все пиксели одного круга будут иметь значение 1, а другого 2. Если с пересечением, то вся область будет иметь значения 1. Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted July 25, 2016 On 22.07.2016 at 5:43 PM, svoyak said: Так отлично, спасибо..есть направление для движения.. а по разделению символов есть какие-то умные пути?? Я понимаю что перебор окном возможно и пойдет, но как то это слегка топорно.. И если не тяжело скажите, зачем применяется ConnectedComponents даже если не сюда все равно интересно:-) Разделение часто делают по гистограмме. Есть у нас изображение шириной W строки с текстом. Тогда заводим массив размером W, каждый элемент которого есть сумма пикселей изображения по столбцам. Сглаживаем, ищем минимумы - они примерно будут соответствовать границам символов. Тут тонкость, что минимумы могут быть локальные, соответствующие не границам, а середине символа. Например, в цифре '0', особенно если она написана трафаретом. Все эти неоднозначности решаются в зависимости от ситуации. Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 25, 2016 Скажите, а скелетизация, как-то повлияет на качество? я фильтрами вроде делаю буквы более менее ровными без разрывов, но надо сказать они такие слегка толстые получаются..в смысле линии их написания. Думаю делать из них скелетов, али нет..Спасибо. Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted July 26, 2016 Я слабо представляю, чем может помочь скелетизация при распознавании символов. Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 27, 2016 Подключил я 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 выводил чтоли.. но вот беда, кудато эта фишка пропала.. и теперь я не вижу процесса. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 27, 2016 Обучите в матлабе, и сдерите оттуда обученную сеть, делал так в одном проекте, очень удобно. Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 27, 2016 Хм.. я так понимаю совместимость там подразумевается?? мне почему-то кажется что проблема не в инструменте, а в данных или их количестве.. как я уже сказал, тестовый пример работает отлично, притом что я перестроил его сеть...сейчас запустил 10000 итераций - закончит посмотрю на изменения.. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 27, 2016 Да я к тому, что в матлабе быстрее диагностику проводить, посмотреть учится/не учится, какая точность, подстроить архитектуру сети, да и алгоритмы в матлабе весьма неплохие. Все можно делать через GUI при помощи: nprtool . А так то веса и в Африке веса, прямой ход - пара матричных операций в конечной программе сделать несложно. Часто еще ошибку с предобработкой входных данных допускают. При обучении нормируют одним образом, а при использовании не нормируют или нормируют как то по-другому. Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 27, 2016 Хм.. а я вот не нормировал вовсе данные, как получились после всяких фильтров opencv, привел к одному размеру и сделал бинарные есно после этого в сеть. Надо нормировать?? я читал об этом, но к сожалению пример по которому я работал без нормирования был.. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 27, 2016 При использовании нормирования, учится быстрее и стабильность лучше. Я к тому, что препроцессинг и формат данных должен быть одинаковый, при обучении и при конечном использовании. Например, есть бинаризация по порогу 100, при получении данных для обучения, точно такую же нужно поставить и режим классификации. Использовались чередующиеся 3 канала RGB, использовать чередующиеся 3 канала RGB в обоих случаях и в том же самом порядке и т.д. UPD: Вообще я делал простенький пример на эту тему. Здесл лежит см. предпоследний пост. Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 28, 2016 Так,c сетью я разобрался..точней с результатами ее работы..как всегда ошибка в днк:-))(моём), я неправильно тренировочный файл делал, причем совсем немного, но фатально.. Есть вопрос еще вот такой... есть два типа шрифтов как их привести к чему-то общему, мне кажется если это сделать, то нейросети будет легче обучаться.. И еще, можно ли с помощью opencv сделать выделение как в фотошопе эффект "волшебная палочка"? В приложении типы шрифтов. 121143.bmp 125724.bmp т.е. получается что в одном шрифте символ грубо говоря белый с черной окантовкой, в другом просто весь черный. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 28, 2016 Думается не нужно преобразовывать данные, сеть сама это сделает в наиболее удобной ей форме, просто нужно дать достаточно обучающих примеров. Касательно "волшебной палочки" посмотрите floodFill, там есть режим маски, или поиск контуров с флагом искать внешний (CV_EXTERNAL или как то так. ). Кстати, можно еще сделать dilate + erode, это заполнит пустоты внутри штриха. Share this post Link to post Share on other sites
svoyak 0 Report post Posted July 28, 2016 Да,dilate + | erode тут поможет как раз линии становятся толстыми и пустоты внутри в процентном соотношении уменьшаются.. Вопрос в том как это будет влиять на изначально полностью черный шрифт.. или надо уметь отличать белый шрифт с черным контуром от просто черных букв, чтоб применять только к первым.. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 28, 2016 А зачем? C черными такая операция ничего не должна сделать, ну может самую малость поменяет контур. Share this post Link to post Share on other sites
svoyak 0 Report post Posted August 1, 2016 Подскажите плз, вот есть такое понятие как BlobDetection, вроде бы я понял что оно позволяет выделить области одинакового цвета. Пользовался ктонить этим?? Я посмотрел несколько примеров, но там народ все равно перед пользованием CvBlobDetector перегоняет картинку в Gray, получается этот блобдетектор по оттенкам серого детектит? может у кого нить есть кусочек кода с ним? у меня иногда буквы идут разного цвета и отделить их по цвету от фона и друг от друга - было бы самое оно.Спасибо. пример во вложении Share this post Link to post Share on other sites
Smorodov 578 Report post Posted August 1, 2016 Вот тут посмотрте: https://github.com/OpenCVBlobsLib/opencvblobslib там есть примеры. Share this post Link to post Share on other sites
svoyak 0 Report post Posted August 2, 2016 Пересмотрел я много примеров по BlobDetection, к сожалению на мой взгляд они мне немного не подходят или я их не до конца понимаю. Все они вроде бы бинаризируют изображение перед детекцией, и получается, что цветовые различия теряются.. Т.е. если в указанном мною выше примере буквы будут также иметь разный цвет, но будут соединены - то blobdetection выдаст мне один единственный блоб с двумя буквами вместе, хотя в реале у каждой буквы свой цвет. Share this post Link to post Share on other sites
svoyak 0 Report post Posted August 2, 2016 ооо..гугленье привело к тому, что я просто неправильно называл то, что мне нужно..правильно: opencv color segmentation, пошел читать дальше.. Share this post Link to post Share on other sites