Повышение визуального качества для фотографий документов

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

    Прежде всего, отметим, что простое увеличение контраста относительно среднего уровня сигнала в большинстве случаев не работает, как видно на рисунке:



    Слева – исходное изображение, справа – результат увеличения контраста.

    Видно, что необходим более сложный алгоритм, учитывающий неравномерность освещения. Попробуем сделать адаптивное увеличение контраста относительно локального среднего значения. Локальное среднее значение вычисляется для каждого пикселя в пределах квадратной окрестности, центром которой он и является. Размер окрестности следует выбирать исходя из ожидаемых размеров букв и толщины штриха. Существуют алгоритмы для быстрого вычисления локальных средних значений, например, интегральная матрица (summed area table). Если перед увеличением контраста из локального среднего вычесть константу, соответствующую оценке уровня шума в изображении, то для простых документов результат может быть вполне удовлетворительным:



    Слева – карта «порогов» (уровней яркости), относительно которых происходит увеличение контраста. Справа – результат применения.

    Можно также увеличивать контраст относительно среднего значения между локальным минимумом и максимумом.

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



    Слева – исходное изображение, справа – результат увеличения контраста.

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

    Задача состоит в том, чтобы каким-то образом построить такую карту «порогов», относительно которой увеличение контраста приводило бы к повышению визуального качества, и которая учитывала бы особенности документов со сложной версткой. Такая карта порогов будет полезна и для получения бинаризованного (черно-белого) изображения документа. Процесс бинаризации можно рассматривать как частный случай, когда увеличение контрастов в изображении стремится к бесконечности.

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



    Разложение начинается с масштаба исходного изображения. Оно делится на непересекающиеся квадраты размером 2х2 пикселя, в каждом из которых мы получаем значения минимума, максимума и среднего из 4-х пикселей, его составляющих. Далее из этих значений формируем три изображения: минимумов, максимумов и средних, которые уменьшены в 2 раза по горизонтали и вертикали относительно исходного. Повторяем процедуру и раскладываем полученные изображения в пирамиды до уровня, на котором размер ещё составляет не менее 2 пикселей по горизонтали и вертикали.

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

    Алгоритм построения карты порогов на основе пирамидального разложения состоит в следующем:
    1. На нижнем уровне пирамидального разложения, где изображение состоит всего из нескольких пикселей, инициализируем карту порогов с использованием любой из двух гипотез:
      • локальное среднее значение этого участка изображения (т.е. яркость пикселя из пирамиды средних)
      • среднее между локальным минимумом и максимумом (среднее по яркости 2-х пикселей, взятых из пирамид минимумов и максимумов).
    2. Переходим на следующий уровень разложения, увеличивая карту порогов в 2 раза по горизонтали и вертикали с применением интерполяции со свертками [1 3], [3 1].
    3. В каждом пикселе на новом уровне пирамидального разложения вычисляем разницу между значением пикселя из пирамиды максимумов и значением из пирамиды минимумов. Если эта разница не превосходит шумовой порог, считаем, что полезного сигнала в этом участке изображения нет, причем как на этом, так и на последующих уровнях пирамидального разложения. Следовательно, значение порога, полученного на предыдущем уровне разложения, можно оставить без изменений. В противном случае вычисляем новое, уточненное значение порога, исходя из смеси двух гипотез, 1а и 1б.
    4. Шаги 2 и 3 повторяем до тех пор, пока не достигнем такого уровня разложения, на котором участки изображения, соответствующие пикселям в пирамиде, ещё обладают размером, превосходящим самые маленькие буквы, различимые на изображении. Обычно такие буквы имеют размер около 6-10 пикселей, этому соответствует 3-й или 4-й уровень пирамиды.


    В результате получаем карту порогов, относительно которой увеличение контраста не приводит к потерям объектов различного размера, кроме того, плоские однородные участки на изображении не содержат шум:



    Слева – карта порогов, справа – результат увеличения контраста относительно неё.

    Остается решить, как быть в отношении цветных изображений, поскольку увеличение контраста часто приводит к потерям в цвете. Можно увеличивать контраст для компоненты яркости (серого изображения), учитывая участки с насыщенным цветом, снижая на них коэффициент увеличения контраста.

    Используем своё цветовое пространство, похожее на HSL, но вместо яркости L будем работать с компонентой Y в цветовом пространстве YCbCr.

    Для серого изображения контраст увеличивается так:
    Y’ = k(Y – T) + T, где Т – значение яркости для этого же пикселя из карты порогов, Y и Y’ – исходное и получаемое значение яркости пикселя, k – коэффициент увеличения контраста, обычно его значение лежит в диапазоне от 3 до 6.

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

    Для участков со слабой насыщенностью можно, напротив, снижать насыщенность цвета вплоть до 0, подавляя цветовой шум на изображении. Это легко сделать, смешивая значения из цветовых каналов с яркостью в различной пропорции. Также полезно перед увеличением контраста сделать выравнивание баланса белого на изображении по гистограммам каналов R, G, B.



    Слева – исходное изображение, справа – результат увеличения контраста с учетом насыщенности цвета.
    ABBYY
    Решения для интеллектуальной обработки информации

    Comments 30

      +26
      Цены бы вам не было, если бы вы показали реализацию такой обработки на практике!
        +4
        Ага, особенно на Leptonica.
        Или сразу готовый патч для Tesseract =)
          +2
          Вот-вот, все ждал, когда же ссылку на прогу/инструмент дадут))
          Увы.
          +6
          И где это посмотреть в действии?
            +4
            Этот алгоритм с некоторыми доработками, возможно, будет встроен в ближайшие версии FineReader Professional, в текущей версии FineScanner (для iOS) в цветном режиме обработки используется похожий алгоритм, учитывающий особенности архитектуры GPU.
            +1
            Не думали о плагине для ImageJ?
              +11
              С удовольствием бы пользовался веб-сервисом который умеет так обрабатывать документы. Сканера нет, а с фотографий качество приходится муторно вытягивать.
                +2
                Для Android есть приложение CamScanner, а так же приложение Google Drive умеет делать то же самое перед загрузкой фотографий документов на диск.
                  +2
                  А на iOS очень хорошо работает Genius Scan.
                    +3
                    Для iOS есть ABBYY FineScanner от авторов поста :).
                      0
                      Алгоритм там несколько отличается от приведенного в силу особенностей архитектуры GPU.
                    0
                    Спасибо за наводку, драйв вполне устраивает. Десктопный/облачный это умеет?
                      0
                      Десктопным не пользовался, в браузерном не нашёл такого, может плохо искал.
                      +1
                      Что, именно прям то же самое, в том же качестве? С пирамидальной картой порогов?
                        +1
                        Естественно, я понятия не имею :). Кода-то не видел. Да, с фразой «то же самое», загнул. Скорее, нечто подобное.
                    +2
                    Из алгоритмов адаптивного повышения яркости мне больше всего вот этот нравится: www.academic-journals.org/ojs2/index.php/ijecs/article/viewFile/1076/113 (Adaptive Smoothing
                    , там про него один раздел)
                    Конечно, он в первую очередь ориентирован на реальные изображения, но там не менее идея итеративного повышения яркости очень неплохо позволяет бороться с тенями.
                      +4
                      Фотографии данный алгоритм все равно заметно портит.
                      В особенности лица (ИМХО для фотографий алгоритм динамического контраста не подходит, их нужно просто выделить и обработать отдельно):


                        +4
                        Этот алгоритм (а вернее, представленная здесь его настройка) больше ориентирован на документы, для фотографий можно воспользоваться этой же идеей, только алгоритм придется настраивать по-другому. Общим у них является использование «изображений» локальных минимумов, максимумов и средних, а вот коэффициент контрастирования и количество уровней в пирамидальном разложении нужно подбирать по-другому.
                        +1
                        Очень актуальная тема. Радует, что ею занялись профессионалы.
                          0
                          Простите, за возможно, глупый вопрос, но что есть «карта порогов»? И как с ее помощью можно получить изображение повышенной контрастности/бинарное изображение?
                            +4
                            Карту порогов можно представить в виде полутонового изображения (2-х мерной матрицы чисел), содержащего вместо сигнала яркости значение порога бинаризации для каждой точки. Для бинаризации порог можно использовать так: значения пикселей исходного изображения выше порога заменяются белыми (максимальными), ниже — черными (минимальными). Для контрастирования мы просто берем разницу между значением яркости в каждой точке и значением порога, разность умножаем на коэффициент контрастирования k > 1, и прибавляем полученную величину с учетом знака обратно к значению порога. Получаем значение пикселя для изображения повышенной контрастности. В тексте есть формула: Y’ = k(Y – T) + T. Y и T здесь являются дискретными функциями от координат пикселей: Y(x,y) и T(x,y). Чтобы получить все изображение, нужно провести вычисления для всех пикселей изображения.
                              0
                              Большое спасибо, теперь все на своих местах.
                                0
                                Еще вопрос, а как вы оцениваете уровень шума на изображении?
                                  +1
                                  Оценка дисперсии (второго момента) может производиться самыми разными способами. Можно попробовать разбить изображение на квадратные области заданного размера, скажем 32х32 пикселей, посчитать для каждого значения первого и второго моментов (среднего и дисперсии), и выбрать несколько с минимальной дисперсией из различных диапазонов среднего, т.е. яркости (их может быть порядка 10). Крайние диапазоны по яркости ненадежны, т.к. сигнал уходит в насыщение (тень или засветка), и измерения в них недостоверны. А вот по остальным можно даже получить зависимость дисперсии от яркости. Для большей надежности можно квадратные области делать пересекающимися или искать минимум для каждого диапазона яркости в скользящем окне (для всех диапазонов за один проход, конечно).
                                  Можно даже собрать статистику для различных камер и их настроек (ISO, шумодав). Порог для шума следует выбирать пропорционально полученным значениям дисперсии, обычно коэффициент для порога лежит в диапазоне от 3 до 5 «сигм» для различных «типов» шума.
                                  0
                                  И еще, вот на этом изображении в правом нижнем углу на однородной черной области вдруг появилась светлое пятно. Это нормально?
                                    +1
                                    Это недостаток алгоритма, в этом месте немного не хватило коэффицента контрастирования, а делать его более высоким всегда — опасно. В цветном пятна не видно, т.к. вся область содержит насыщенный цвет и для неё мы снижаем коэффициент контрастирования практически до 0, в результате цвет выравнивается. Вообще, задача бинаризации документов со сложной версткой до сих пор не имеет однозначного решения для всех случаев. Но мы к этому стремимся. :)
                                +1
                                Для виндофона МС выпустила похожую по функциональности Office Lens. Там есть режим «доски» где на фото находится доска (похоже что любой прямоугольник), центрируется, выравнивается, убираются блики, улучшается контраст (правда не знаю, такой-же ли у них продвинутый алгоритм). Вот примеры:

                                Постер: oригинал, и после обработки.

                                Доска: оригинал, и после обработки.
                                0
                                Извиняюсь за некропостинг, пост показали только недавно.

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

                                Если читать текст буквально, то кажется возможен странный эффект.

                                Предположим, в среднем документ довольно ярок, т.е. средний уровень предположим где-то около 0.7, а максимум и минимум — пусть 0.5 до 1.0. В этом случае, алгоритм перестанет делать локальные изменения порогов вообще — уровень порога, приходящий с верхнего уровня будет 0.7, разница между максимальным и минимальным не больше — 0.5, следовательно делать ничего не нужно на всех уровнях.

                                Казалось бы, хочется не такого поведения, а как раз вычесть среднее (0.7) и улучшать контраст в разных частях документа.

                                Поясните плз?
                                  0
                                  Там два порога: порог контрастирования, который мы уточняем, двигаясь по масштабам вверх, и шумовой порог, который является константой, зависящей от уровня шума в изображении. Обычно на реальных деталях изображений разница между локальным максимумом и минимумом составляет 0.3-0.7, а шум — не более 0.1. Поэтому происходит как раз то, что вы описали, порог уточняется для различных участков изображения до тех пор, пока там есть детали все более мелкого масштаба, превосходящие по контрасту шум.

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