Какие этапы обработки я должен использовать, чтобы очистить фотографии штриховых рисунков? - PullRequest
13 голосов
/ 08 января 2011

Мой обычный метод 100% -ой контрастности и некоторой регулировки яркости для настройки точки среза обычно работает достаточно хорошо, чтобы очистить фотографии небольших подсхем или уравнения для публикации на E & R.SE, однако иногда это не так уж и здорово, например, с этим изображением:

alt text

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

Я ожидаю довольно общий ответ, но я, вероятно, реализую его в сценарии (в который я могу просто записывать файлы), используя ImageMagick и / или PIL (Python), так что если у вас есть что-то конкретное, оно будет добро пожаловать.

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

Ответы [ 3 ]

17 голосов
/ 08 января 2011

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

from PIL import Image
from PIL import ImageFilter
im = Image.open(r'c:\temp\temp.png')
white = im.filter(ImageFilter.BLUR).filter(ImageFilter.MaxFilter(15))

alt text Следующим шагом является создание полутонового изображения на входе RGB.Масштабируя до белой точки, мы исправляем проблемы с балансом белого.Взяв максимум R, G, B, мы преуменьшаем любой цвет, который не является чисто серым, например синие линии сетки.Первая строка кода, представленная здесь, является фиктивной, для создания изображения правильного размера и формата.

grey = im.convert('L')
width,height = im.size
impix = im.load()
whitepix = white.load()
greypix = grey.load()
for y in range(height):
    for x in range(width):
        greypix[x,y] = min(255, max(255 * impix[x,y][0] / whitepix[x,y][0], 255 * impix[x,y][2] / whitepix[x,y][3], 255 * impix[x,y][4] / whitepix[x,y][5]))

Результатом этих операций является изображение, которое имеет в основном согласованные значения и может быть преобразовано в черныйи белый через простой порог.alt text


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

Моя попытка воссоздатьэтот подход привел к следующему:

for y in range(height):
    for x in range(width):
        greypix[x,y] = min(255, max(255 + impix[x,y][0] - whitepix[x,y][0], 255 + impix[x,y][7] - whitepix[x,y][8], 255 + impix[x,y][9] - whitepix[x,y][10]))

alt text

Я работаю над сочетанием методов для достижения еще лучшего результата, но он еще не совсем готов.

17 голосов
/ 08 января 2011

Один из распространенных способов убрать различную фоновую подсветку - вычислить «белое изображение» на изображении, открыв изображение.

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

src = imread('lines.png');
blue = src(:,:,3);
mask = fspecial("disk",10);
opened = imerode(imdilate(blue,mask),mask);

Результат: opened

Затем вычтите это из исходного изображения:

background_subtracted = opened-blue;

background_subtracted (контрастная улучшенная версия)

Наконец, я бы просто оцифровал изображение с фиксированным порогом:

binary = background_subtracted < 35;

binary

3 голосов
/ 08 января 2011

Как насчет обнаружения ребер ? Это должно подобрать чертежи.

Вот результат обнаружения края Собеля на вашем изображении:

alt text

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

Как указал Ламберт, вы можете предварительно обработать изображение, используя синий канал, чтобы избавиться от линий сетки, если вы не хотите, чтобы они были в вашем результате.

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

...