Локальная версия «Баланс белого» в GIMP для очистки фотографии документа

У меня есть фотография документа с черным текстом на белом фоне.

На фото есть несколько проблем:

  • Текст немного размыт.
  • В целом есть шум даже в белых областях.
  • Фон кажется не совсем белым, а немного желтоватым.
  • Самое главное: некоторые области изображения, даже те, которые должны быть белыми, темнее других.

Я хотел бы очистить эту картину. Я на Линуксе.

Фильтр «Цвета > Авто > Баланс белого» в GIMP дает многообещающие результаты. Однако он не выравнивает фон в разных областях изображения.

Но если я выберу только подобласть изображения, фильтр «Баланс белого» на самом деле работает лучше в этой области.

Так что я полагаю, что постепенное применение «Баланс белого» в локальных областях изображения будет работать очень хорошо.

Я представляю, что фильтр "Баланс белого" реализован так:

  1. Соберите цветовую статистику всего изображения.
  2. Создайте матрицу преобразования цвета и примените ее глобально.

Итак, что я хотел бы вместо этого:

  1. Соберите локальную статистику цвета для каждой области, например, 100 * 100 пикселей.
  2. Создавайте матрицы преобразования локальных цветов.
  3. Построить непрерывную функцию матриц преобразования на пиксель.
  4. Применять локально для каждого пикселя.

Знаете ли вы что-нибудь подобное, что существует либо в GIMP, либо в виде независимой части программного обеспечения, например, для командной строки Linux?

Простое обесцвечивание изображения не сработает для вас?
Или увеличивать экспозицию до тех пор, пока все, кроме черного отпечатка, не исчезнет?
@MichaelClark Я сфотографировал документ на свою мобильную камеру. Он не имеет контроля за экспозицией. Также освещение не является оптимальным. И я не люблю вспышку, потому что она создает отражения и неравномерное освещение.
@junkyardsparkle Desaturate просто превращает изображение в оттенки серого. Основная проблема, которую я не могу легко решить, — это изменение фона.
Я исправил маркированный список в вопросе. Основная проблема, о которой идет речь в этом вопросе, заключается в том, что уровень белого фона распределяется неравномерно.
@donquixote Вы также можете увеличить яркость/экспозицию в посте. Если ваша мобильная камера не сохраняет файлы в необработанном формате, это усложняет задачу. Но вот в чем дело: вы, кажется, отказываетесь правильно освещать, чтобы компенсировать свою ограниченную камеру, в то же время вы отказываетесь использовать более мощную камеру, чтобы компенсировать ваше ограниченное освещение.
У меня был некоторый успех с приложением Microsoft OfficeLens. Я не знаю, какие фильтры он использует внутри. И это работает только в том случае, если вы снимаете фотографию непосредственно с помощью этого приложения, оно не предназначено для последующей обработки.
Еще одна вещь, которую я пробовал: использовать медианный фильтр или «нижний медианный фильтр», чтобы получить оценку фона, а затем вычесть этот фон из исходного изображения. Я сделал это с помощью PHP-скриптов, поэтому моя реализация не очень полезна для других. Но мысль правильная. Эта идея похожа на ответ от клабаккио.

Ответы (4)

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

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

Альтернативным подходом может быть дублирование слоя (я сделал снимок, затеняя рукой половину карты, чтобы воспроизвести проблему):

Размывайте его, пока текст не исчезнет:

введите описание изображения здесь

Затем вычтите полученный слой из исходного, выберите режим наложения «Зернистый экстракт», чтобы обратить неравномерность освещения:

введите описание изображения здесь

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

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

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

введите описание изображения здесь

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

Я подозреваю, что ваш второй подход не сработает, если текст не будет очень разреженным. Но первый кажется хорошей идеей
@ChrisH Я пробовал и, на самом деле, считаю, что это может быть эффективно. Я согласен с вами, что более плотный текст может быть проблемой, но не такой большой, если вы достаточно размоете. Очень жирный и разреженный текст может быть еще хуже.
Очень хорошо. Это то, о чем я думал как о чем-то редком по сравнению с чем-то вроде письма.
Да, это выглядит идеально! Но вместо размытия (которое, как я предполагаю, просто берет среднее значение соседних пикселей), я бы предложил использовать медиа-фильтр. К сожалению, я не могу найти такой фильтр в Gimp. Конечно, в идеальном мире это уже было бы объединено в пакет, потому что я думаю, что вариант использования довольно распространен. Но я так и не нашел этого до сих пор.
Кстати, я думаю, что в вашем примере я бы сказал, что фон идеален, но некоторые черные круги выглядят немного поврежденными или слишком сжатыми.
@donquixote, конечно, результат можно улучшить, у меня ушло 10 минут, а я не эксперт. Если вы хотите большего качества, я думаю, что использование инструмента клонирования на слое, который нужно размыть, может помочь, как и лучшее смешивание. Но принцип есть, и это можно было бы сделать в пакетном режиме
Я думаю, что круги слева были переэкспонированы на последнем шаге, они выглядят почти нормально на предыдущем изображении. надо попробовать еще раз

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

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

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

Как только ваш фон станет белым (rgb 255 255 255) далеко от текста, может потребоваться локальное удаление пятен.

Хотя я знаю, что у меня есть примеры, подтверждающие это, у меня нет сохраненных промежуточных шагов.
Существует компромиссный подход к порогу: постеризация до небольшого нечетного числа (я обычно экспериментирую с 3 до 15 и в итоге выбираю 3 или 5). Это в значительной степени дает чистоту порога с небольшим сглаживанием.
@PeterTaylor Мне придется попробовать это некоторое время и посмотреть, как это сравнивается с моим подходом к крутым уровням.
@ChrisH Спасибо за ответ. Но на самом деле это не решает основную проблему, заключающуюся в неравномерном освещении фона.
@donquixote IME (и я делал это довольно часто), он решает эту проблему. Хотя я не думаю, что это отличный ответ на ваш вопрос, я думаю, что это достойный ответ на вашу проблему. Не могли бы вы опубликовать (отредактировано, если необходимо) изображение?
... если только вариация не настолько велика, что черный цвет в одной области близок к белому в другой.
да это то, что я боюсь, что произойдет. Это может не устранить буквы в более ярких областях, но я подозреваю, что уменьшит их. Я предполагаю, что алгоритм с «локальным» балансом белого повсеместно предотвратил бы это.

...режим смешивания как "Экстракт зерна"

Режим «Деление» также создает приятные эффекты для документов (более контрастные).

Привет Ласкус, добро пожаловать на сайт. Можете ли вы предоставить более подробную информацию о том, как использовать режим «Отделение» и что он делает? Это может быть многообещающая информация о том, что пытается сделать ОП, но она имеет ограниченную ценность без объяснения того, как ее использовать.
Я только что попробовал это; режим наложения слоя «Разделить» имеет более быстрый эффект, чем «Извлечение зерна»; результат аналогичен переходу прямо к последнему шагу в ответе @clabacchio. Однако, поигравшись, я иногда получаю более чистый текст с помощью метода Grain Extract/curves, так что, вероятно, это зависит от входного изображения. В любом случае, шаги для этого таковы: продублируйте базовый слой, размойте, установите режим наложения на «Разделить». Что именно он делает, см . docs.gimp.org/en/gimp-concepts-layer-modes.html .

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

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

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

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

  • Соберите все пиксели поблизости, например, 100 = 10x10 пикселей.
  • Отсортируйте их по яркости.
  • Используйте 50-е самое яркое значение цвета в качестве нового значения цвета для центрального пикселя. Или 10-е самое темное значение цвета для «нижней медианы».

Это дает вам оценку фона. Однако он, вероятно, будет содержать «шаги» в цветах из-за того, как работают медианы. Может быть, есть что-то еще умнее этих медиан.

При желании используйте сглаживание (большой радиус), чтобы устранить эти шаги.

Теперь вычтите этот слой из исходного изображения.

При желании используйте «баланс белого» для результата (если вы работаете с GIMP).

Я не знаю, какой инструмент мне выбрать, если я хочу реализовать все это. До сих пор я использовал PHP, но я не уверен, что это вообще лучшее решение.