Неравномерное освещение

Как избавиться от неравномерного освещения от изображений, которые содержат текстовые данные, которые обычно печатаются, но могут быть написаны от руки? На нем могут быть пятна света, потому что свет отражается при создании изображения. Я видел, что функция plot_characters в программе Halcon отлично справляется с этой работой, но не имеет открытого исходного кода. Я хочу преобразовать изображение в изображение с постоянной подсветкой на фоне и более темными областями текста. Так что бинаризация будет легкой и без шума. Предполагается, что текст темнее, чем фон. Есть идеи?

5 ответов

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

1) Расчет средней интенсивности всех пикселей на изображении

2) Использование замыкания на реконструкцию для оценки уровней фоновой освещенности

3) Вычтите вывод (2) из ​​исходного изображения

4) Добавление средней интенсивности от (1) к каждому пикселю на выходе (3).

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

Используйте локальный порог вместо глобального алгоритма порога. Разделите ваше изображение (в градациях серого) на сетку из небольших изображений (скажем, 50x50 px) и примените алгоритм порогового значения к каждому отдельному изображению.

Строго говоря, при условии, что у вас есть доступ к пикселям изображения (вы можете найти в Интернете, как выполнить это на своем языке программирования, поскольку тема доступна в изобилии), упражнение включает в себя один раз просмотр пикселей, чтобы определить "порог темноты". Для этого вы конвертируете каждый пиксель из RGB в HSL, чтобы получить компонент уровня яркости для каждого пикселя. Во время этого процесса вы рассчитываете среднюю яркость для всего изображения, которую вы можете использовать в качестве "порога темноты"

Получив средний уровень яркости изображения, вы можете еще раз пройти пиксели изображения, и если пиксель меньше порога темноты, установите его цвет на полностью белый RGB(255 255 255), в противном случае установите его цвет на полностью черный RGB (0,0,0). Это даст вам двоичное изображение, в котором текст должен быть черным, остальное должно быть белым.

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

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

РЕДАКТИРОВАТЬ

Для дальнейшего чтения о HSL я рекомендую начать с записи Wiky о цветовых пространствах HSL и HSV.

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

После этого есть две хитрости.

1) Используйте оператор smooth_image(), чтобы свернуть гауссовский язык на исходном изображении. Используйте относительно большое ядро, например 20-50 пикселей. Затем вычтите это размытое изображение из исходного изображения. Примените масштаб и смещение в операторе sub_image() или используйте equ_histo() для выравнивания гистограммы.

Это в основном вычитает информацию о низкой пространственной частоте из оригинала, оставляя нетронутой информацию о более высокой частоте.

2) Вы можете попробовать оператор highpass_image() или один из лапласовских операторов для извлечения градиентного изображения.

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

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

Здесь также объясняется простой, но эффективный метод. Простая схема этого алгоритма следующая:

  1. Разделить изображение на NxN регионов или районов
  2. Рассчитать среднее или медианное значение пикселя для окрестности
  3. Порог области на основе значения, рассчитанного в 2) или значения из 2) минус C (где C является выбранной константой)

Если фоновые элементы обычно больше, чем буквы, вы можете попытаться оценить и впоследствии удалить фон.

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

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

Другие вопросы по тегам