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

    Я иногда путешествую по разным странам, и языковой барьер, довольно часто, становится серьезным препятствием для меня. И если в странах, где используются языки германской группы, я еще как то могу сориентироваться, то в таких странах как Китай, Израиль и арабские страны без сопровождающего, путешествие превращается в загадочный квест. Невозможно понять местное расписание автобусов/поездов/электричек, названия улиц в небольших городах очень редко есть на английском языке. А уж проблема с выбором, что бы поесть, из меню на непонятном языке вообще сродни ходьбы по минному полю.
    Так как я разработчик под iOS, я подумал, а почему бы не написать такое приложение: наводишь камеру на вывеску/расписание/меню и тут же получаешь перевод на русский.

    Краткий поиск по App Store показал, что имеется всего одно или два подобных приложения, причем русский язык не входит в число поддерживаемых. Значит, путь открыт и, можно попробовать, написать такое приложение. Тут стоит оговориться, что разговор не идет о тех приложениях, которые фотографируют черный текст на белом листе бумаги и потом оцифровывают и переводят его. Таких приложений действительно вагон и маленькая тележка. Речь идет приложении, которое может выделить текст на естественном изображении, например на фотографии автобуса необходимо выделить текст на маршрутной табличке и перевести его, чтоб пользователь мог понять, куда идет этот автобус. Или актуальный для меня вопрос с меню, очень уж хочется знать, что ты заказываешь поесть.

    Основная задача в приложении, это детектирование и локализация текста, а затем его выделение и бинаризация для «скармливания» в OCR, например tesseract. И если алгоритмы по обнаружению текста в сканированных документах уже давно известны и достигли 99% точности, то обнаружение текста произвольного размера на фотографиях до сих пор является актуальной областью исследований. Тем интереснее будет задача, подумал я и взялся изучать алгоритмы.
    Естественно, универсального алгоритма для нахождения любого текста на любом изображении не существует, обычно используется разные алгоритмы для разных задач плюс эвристические методы. Для начала, формализуем задачу: для наших целей необходимо найти текст, который достаточно контрастен с окружающим фоном, расположенный горизонтально, угол наклона не превышает 20 градусов, и он может быть написанный шрифтом разного размеров и цвета.

    Просмотрев алгоритмы, я принялся изобретать велосипед взялся за реализацию. Решил писать все сам, без использования opencv, для более глубокого погружения в предмет. За основу взял, так называемый, edge based метод. И вот, что в итоге у меня получилось.
    В начале получаем изображение с камеры телефона в формате BGRA.


    Переводим его в grayscale и строим гауссову пирамиду изображений. На каждом уровне пирамиды, будем находить текст определенной размерности. На самом низком уровне мы детектируем шрифты высотой, примерно, от k до 2*k- 1 пикселей, затем от 2*k до 4*k-1 и так далее. Вообще то надо было использовать 4 изображения в пирамиде, но мы помним, что в нашем распоряжении всего лишь iPhone, а не четырехядерный i7, по этому ограничимся 3-мя изображениями.


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


    К выделенным оператором Собеля вертикальным границам, применим морфологическую операцию закрытия. По горизонтали на ширину шрифта, а по вертикали на 5. Полученный результат опять отфильтровываем. Пропускаем только то что укладывается в высоту искомого нами шрифта от k до 2*k- 1, и длиной не менее 3-х символов. Получаем вот такой результат.


    Проделываем те же операции со следующим уровнем пирамиды.


    Потом объединяем все результаты в один. Затем в выделенной области делаем адаптивную бинаризацию и получаем в итоге такое изображение. Оно уже вполне пригодно для дальнейшего распознавания в OCR. Видно что самый большой шрифт не определился, из за того что не хватает еще одного изображения в гауссовой пирамиде.


    Ниже приведены примеры работы алгоритма на более сложных изображениях, видно что еще требуется некоторая доработка.
    Время обработки изображения 640х480 на iPhone 5, порядка 0.3 сек.

    P.S. На вопросы отвечу в коментах, про грамматические ошибки пишите в личку.





    Similar posts

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 41

      0
      Думал в конце будет линк :)) идея классная, ничего не скажешь. Еще бы фотка не сохранялась а вместо этого в заметках появлялся текст например (можно в заметках софтинки самой)
        +2
        Само приложение еще не готово, в разработке.
          0
          Да, я понимаю) молодец вы, думаю будет востребованным приложением, причем учитывая полезность, думаю и платность не помешает :) я бы взял
            0
            Если не преследуете коммерческие интересы, можете выложить то, что уже есть, на GitHub. Будет интересно почитать.
          0
          Хотелось бы больше подробностей, описаний алгоритмов на псевдоязыке и так далее.
            0
            Распознавать планируете в tesseract?
            0
            Был бы благодарен, в конце поста увидеть ссылки, откуда брали информацию для реализации (оператора Собеля, пирамиды Гаусса, адаптивной бинаризации). Или хотя бы описание алгоритмов
              0
              Оператор Собеля:

              Гауссова пирамида изображений: «Для получения слоя (i+1) в Гауссовской пирамиде из слоя i пирамиды, нам необходимо сначала свернуть этот слой с помощью Гауссовского ядра, а затем удалить все чётные строки и столбцы. Конечно из этого следует что каждое последующее изображение будет занимать четверть площади его предшественника.»
                0
                С оператором, ясно, спасибо (я в вики уже нашел). А вот с пирамидой, можно более конкретно?
              0
              Тестировали производительность с четырьмя изображениями в гауссовой пирамиде изображений?
                0
                Нет с 3-мя
                  0
                  Попробуйте протестировать. Может, не так уж и затратно будет.
                +1
                Можно предусмотреть ручного указания области фотографии для распознавания, задания прямоугольника, ведь часто нужна только конкретная область.
                  0
                  Это конечно можно, но из моего опыта, пользователи айфонов, в большинстве своем, такие люди что им нужна одна кнопка «Сделать красиво». Так что в своем приложении я этого не планирую.
                    0
                    Ну, при сильно зашумлённом изображении, если автомат не прошёл, можно, думаю, выводить диаложек — попробуйте указать интересующую область вручную… не?
                      0
                      Может быть и так, но проще изменить ракурс и переснять.
                  0
                  Я делал подобную задачу под андроид, но там надо было распознавать автомобильные номера
                  Столкнулся с такими проблемами — очистка от шума, искажения и т.д.
                  Я, правда boofCV использовал, так как реализовывать все алгоритмы было довольно утомительно, например морфологические операции, кэнни
                  Да и как показывает практика — функции, реализованные в таких библиотеках хорошо оптимизированы по быстродействию и использованию памяти, что очень критично на мобильных девайсах
                  В итоге я использовал кэнни, затем фильтровал области по размеру и скармливал в OCR по одному символу — получилось довольно эффективно
                    0
                    Позвольте поинтересоваться. Вы реализовывали только распознавание или еще и поиск номера?
                    В данный момент, как раз работаю над такой задачей. И успешный поиск автомобильного номера происходит в ~80-85% случаев(что меня не очень устраивает).
                    Если вы работали над поиском, то было бы интересно узнать процент успешной локализации номера и, если не секрет, в общих чертах алгоритмы.
                      0
                      Конечно необходимо было номер найти и локализовать. Для этого я искал прямоугольники на изображении с определенным процентом заполнения черными пикселями. В версии для десктопа я использовал opencv и пример для поиска прямоугольников который идет в комплекте с этой библиотекой. Процент попаданий, к сожалению был не очень большой — процентов 60-80, так как картинки были в разных качествах, под разными углами, но я алгоритм потихоньку оптимизирую. Кроме этого возникнет проблема ложных срабатываний, понадобится дополнительный фильтр по ним
                        0
                        А как вы искали прямоугольник? С помощью Хафа?
                          0
                          Там функция есть библиотечная findContours, скорее всего работает на основе преобразования Хафа
                            0
                            Вообще-то, она просто составляет список непрерывных линий(контуров) по растровой бинарной картинке.
                              0
                              Да, но я почему-то думал, что ищутся именно линии при этом, принадлежащие одному контору. Интересно, тогда какой алгоритм там используется?
                                0
                                Линии принадлежащие одному контуру? Не совсем понимаю, как это.

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

                                Можно, конечно, глянуть исходники OpenCV, благо они под рукой, но слабонервным этого делать не стоит.
                                  0
                                  «Линии принадлежащие одному контуру? Не совсем понимаю, как это.»

                                  Ну это я заблуждался просто — я вообще думал, что он Хафа для этого использует

                                  «Можно, конечно, глянуть исходники OpenCV, благо они под рукой, но слабонервным этого делать не стоит. „

                                  Кстати говоря исходники там вполне читаемые, хотя сталкивался с трешаком — но это понятно — там же много людей к либе приложили руку
                                    0
                                    Вот была у меня однажды необходимость посмотреть как что-то там реализовано в модуле calib3d.
                                    И поругался и повеселился, но, так и не разобравшись, плюнул на это дело. Реализовал сам.

                                    Сейчас вот глянул contours.cpp. Не знаю, сколько потребуется времени, чтобы загрузить в мозг эти алгоритмы по коду.
                                    Форматирование кода нормальное. Но одно-двух-трех-буквенные названия переменных и дикое обилие magic numbers… нет, я это читать не могу.
                      0
                      Когда пишешь сам, лучше понимаешь как это работает. Можешь изменить пару цифр в алгоритме и сразу видишь что изменилось на выходе. Не знаю как на андроиде, но в opencv под iOS мне кажется, размытие по гауссу делается только с ядром 5. Т.е. ты уже в определенных рамках, а если мне надо ядро 3 или 7. Начинаешь писать сам недостающие функции, так уж легче все с нуля самому написать.
                        0
                        Это да, поэтому, недавно реализовал размытие гаусса в общем виде (для retinex — там ядро большое нужно). Но опять таки моя реализация вышла чуть более требовательной по памяти.
                      –1
                      Большой потенциал видит Йода в этом приложении. Помимо туризма можно и другие применения найти.
                        0
                        Спасибо, а подскажите какие еще применения, а что то мне на ум больше ничего и не приходит.
                          0
                          Как вариант — детектирование торговых знаков/вывесок и поиск инфы в гугле по ним сразу на месте.
                            0
                            вы имеете ввиду Google Goggles?

                            хм, посмотрел описание, оно еще и тексты сканит и переводит :)
                            0
                            У меня во дворе автолюбители часто «запирают» друг друга, оставляя телефонный номер под лобовым стеклом. Неоднократно приходила в голову мысль сделать распознавание телефонного номера по фотографии, чаще эта мысль посещает зимой и в темноте, ближе к лету функция частоты асимптотически стремится к нулю с редкими осцилляциями.
                              0
                              Ну эта штука, по идее, есть команда. То бишь фотографируя какую-то надпись и получая ее в виде текста, мы можем трактовать это как просьбу пользователя сделать что-то с этими данными. Трактовка зависит от вида данных.
                              Например, если сфотографирован номер авто, то получаем по нему какую-то информацию.
                              Или фотографируется какой-то продукт в магазине и по нему получается дополнительная информация.
                              Хочу сказать, что необязательно это в другой стране делать. Может примеры несколько надуманны, но смысл в том, что это как Siri. Только не говоришь в нее запрос, а фотографируешь.

                            +2
                            Под андроид это умеет делать google translate, а под iOS похоже его не научили. Поэтому на айфоне можно воспользоваться google goggles: www.wikihow.com/Translate-With-Google-Goggles
                              +1
                              Если бы он еще не требовал соединения с инетом для отсылки фотографий.
                              +5
                              подобная функциональность уже заявлена в последнем google translate.
                              пока работает плохо, но…

                              P.S. а что касается «ориентироваться в Израиле»… громко и внятно, на всю улицу, на любом доступном Вам языке кричите «И что за х… я тут написана??!» и вам немедленно отвечают.
                                0
                                В свое время я делал штуку для выделения текста (номера автомобиля) и применил построчно для этого прямое и обратное БПФ — после прямого отбрасывал в результате те гармоники, которые относятся к очень низким и очень высоким частотам и делал обратное преобразование. после этого применял нечто, что называл «инерциальный» фильтр — по сути суммировал вдоль строки яркости бегущим окном и если значение было больше порога, то отмечал точку. В результате получал размеченные зоны, где был некоторый ритм, характерный для текста. Это еще в 97-98гг было, работало почти в реальном времени на i486, правда с камеры было невысокое разрешение. БПФ помню еще Watcom C компилировал, а потом руками дооптимизировал, sin & cos по таблице итп.
                                  0
                                  Учитывая развитие google translate и похожих утилит, за то время пока будете дорабатывать продукт можно потерять ЦА.

                                  ИМХО — как раз тут ключевым плюсом была бы дополненная реальность. Чтобы навести телефон на текст, а прога затирала его цветом фона и поверх выводила перевод в том же месте и с теми же искажениями… Если в реальном времени не получится — то хоть на готовой фотке.
                                  Даже в тех макетах что у вас — google translate — просто выдал бы кучу неструктурированного текста, читать который крайне неудобно…
                                    +1
                                    Спасибо за пост и подробное описание именно реализации. Единственное удивило, что не много программ с такой функциональностью (которые поддерживают русский), например, на Nokia Lumia своей пользуюсь Bing Translator (обычно как раз для не English текстов и надписей), который умеет в live-режиме с камеры переводить — вот ссылка на только что сделанный перевод.

                                    Only users with full accounts can post comments. Log in, please.