Які найкращі алгоритми визначення порогу зображення документа в цьому прикладі?


31

Я намагаюся реалізувати різні алгоритми бінаризації до зображеного зображення: введіть тут опис зображення

Ось код:

clc;
clear;
x=imread('n2.jpg');     %load original image

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

size(x);
x=imresize(x,[500 800]);
figure;
imshow(x);
title('original image');

z=rgb2hsv(x);       %extract the value part of hsv plane
v=z(:,:,3);
v=imadjust(v);

% тепер ми знаходимо середнє та стандартне відхилення, необхідні для алгоритмів ніблака та% савули

m = mean(v(:))
s=std(v(:))
k=-.4;
value=m+ k*s;
temp=v;

% реалізації алгоритму порогового значення ніблака:

for p=1:1:500
    for q=1:1:800
        pixel=temp(p,q);
        if(pixel>value)
            temp(p,q)=1;
        else
            temp(p,q)=0;
        end
    end
end
figure;
imshow(temp);
title('result by niblack');
k=kittlerMet(g);
figure;
imshow(k);
title('result by kittlerMet');

% реалізації алгоритму порогу савули:

val2=m*(1+.1*((s/128)-1));
t2=v;
for p=1:1:500
for q=1:1:800
    pixel=t2(p,q);
    if(pixel>value)
        t2(p,q)=1;
    else
        t2(p,q)=0;
    end
end

кінець

figure;
imshow(t2);
title('result by sauvola');

Отримані нами результати такі, як показано: введіть тут опис зображення введіть тут опис зображення введіть тут опис зображення

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


1
Чи можете ви використовувати інформацію про колір, щоб викинути фон замість яскравості?
ендоліт

Шановний сер / пані. Я займаюся проектом по обробці зображень. Я цікава концепція бінаризації. Попросіть перевірити і виправити кодування ... Я беру кодування та запускаю програму. Але виникає якась помилка цього кодування ... Не визначена функція або змінна 'g'. і ще одна - Помилка в msp (рядок 31) k = kittlerMet (g); .. Як її вирішити ... Будь ласка, виправте кодування ...
muthu

Відповіді:


49

У вашому зображенні немає рівномірної яскравості, тому вам не слід працювати з рівномірним порогом. Вам потрібен адаптивний поріг. Це можна реалізувати шляхом попередньої обробки зображення, щоб зробити яскравість більш рівномірною у всьому зображенні (код, написаний у Mathematica, вам доведеться реалізувати версію Matlab для себе):

Простий спосіб зробити яскравість рівномірним - видалити фактичний текст із зображення за допомогою фільтра, що закриває:

white = Closing[src, DiskMatrix[5]]

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

Розмір фільтра слід вибирати більше, ніж ширина шрифту та менше розміру плям, які ви намагаєтесь видалити.

EDIT: У коментарях мене попросили пояснити, що робить операція закриття. Це морфологічна дилатація з наступною морфологічною ерозією . Розширення по суті переміщує структуруючий елемент у кожному положенні зображення і підбирає найяскравіший піксель під маскою, таким чином:

  • видалення темних структур, менших за структуруючий елемент
  • зменшення більших темних структур за розміром елемента, що структурує
  • збільшення яскравих структур

Операція ерозії робить навпаки (вона підбирає найтемніший піксель під усередині структуруючого елемента), тож якщо застосувати його до розширеного зображення:

  • темні структури, які були видалені, оскільки вони менші, ніж структуруючий елемент, все ще відсутні
  • темніші структури, що були зменшені, знову збільшуються до початкових розмірів (хоча їх форма буде більш гладкою)
  • яскраві структури зводяться до початкових розмірів

Таким чином, операція закриття видаляє невеликі темні об'єкти з лише незначними змінами на більш великі темні та яскраві об'єкти.

Ось приклад з різними розмірами структуруючих елементів:

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

Зі збільшенням розміру структуруючого елемента все більше символів видаляється. При радіусі = 5 всі символи видаляються. Якщо радіус збільшується далі, то дрібні плями також видаляються:

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

Тепер ви просто розділите початкове зображення на це "біле зображення", щоб отримати зображення (майже) рівномірної яскравості:

whiteAdjusted = Image[ImageData[src]/ImageData[white]*0.85]

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

Це зображення тепер може бути бінарне з постійним порогом:

Binarize[whiteAdjusted , 0.6]

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


5
Оце Так! Це дійсно круто! Величезний +1!
Phonon

@nikie +1 Дуже добре - що ви маєте на увазі саме після закриття фільтра, щоб його було обрано більше, ніж шрифт? Ширина або довжина будь-якої літери? Крім того, що "справді" робить фіксуючий фільтр? Спасибі!
Спейси

1
@Mohammad: Я додав невелике пояснення до своєї відповіді. І так, це нелінійні операції. Поширений заголовок - це морфологічна обробка зображень.
Нікі Естнер

1
@nikie Неважливо, білий - це макс, а не чорний. :-)
Спейси

1
@gdelfino: Я зазвичай намагаюся уникати цього, використовуючи достатньо велику маску, і використовую Clip[ImageData[white],{eps,Infinity}]там, де eps - це невелика кількість, щоб бути безпечним.
Нікі Естнер

6

Відповідь Нікі здається найкращою, а також, здається, працює і дає результати. Тож це явний переможець.

Однак лише до документації я додаю ще одне посилання, що може бути дуже швидким.

Ця методика називається адаптивним порогом, який не потребує чіткого вивчення фону.

По суті, замість того, щоб знайти найбільш підходящий глобальний поріг - ми можемо розділити зображення на локальне вікно (скажімо, приблизно 7x7 або відповідне) та знайти пороги, які змінюються у міру проходження вікна.

Посилання внизу детально визначає точний метод. http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm

Цей метод був би порівняно обчислювально швидшим.


Хіба ці дві речі по суті не однакові? А саме оцінка локального середнього сигналу до порогового значення?
Маврит

1
@Maurits Схоже, основні відмінності - це впорядкованість та використані статистичні дані. Наприклад, в операторах відкриття / закриття (які складаються з дилатації та ерозії, але в іншому порядку), вікно сканується растровим і приймається макс. (Між іншим). Однак у адаптаційному порозі середнє значення / медіану можна взяти замість макс.
Спейси

ОП запитав це також на SO , на що я відповів. Але в принципі, я не думаю, що між відповідями є різниця, завжди є оцінка місцевої статистики. Якщо ви робите адаптивні порогові показники, ви також дізнаєтесь передумови в процесі.
Маврит

6

Ще один спосіб використання смугового фільтра (в MATLAB). Якщо грати з різницею гауссових параметрів, можна дати кращі результати. В основному цей процес - це смуговий фільтр зображення, щоб видалити низькочастотні фонові краплі, нормалізувати їх до [0,1], необхідних для команди 'grethresh', порогового зображення.

Завантажте зображення та перетворіть у подвійний масштаб:

I = imread('hw.jpg');
I = rgb2gray(I);
I = double(I);

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

Фільтруйте за допомогою різниці ядра Гаусса і нормалізуйте:

J = imgaussian(I,1.5) - imgaussian(I,0.5);
J = J - min(J(:));
J = J / max(J(:));

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

Обчисліть поріг і зробіть 010101:

T = J > graythresh(J);

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


4

Це хороший код Matlab для адаптивного порогування: http://www.mathworks.com/matlabcentral/fileexchange/8647-local-adaptive-thresholding


Арг! Однак потрібна панель інструментів для обробки зображень. : - /
Spacey

Справді. Вибачте, якщо у вас його немає. Але DIPImage - це безкоштовний Image Tolbox для Matlab. diplib.org/documentation У ньому є кілька методів визначення порогу (розділ перевірки сегментації), і ви також можете виконувати всі морфологічні операції, такі як закриття. Також у розробника є блог cb.uu.se/~cris/blog/index.php/archives/tag/matlab
MyCarta

0

Я спробую це кодування. Але у мене немає правильної відповіді ...

clc;
clear;
x=imread('base2.jpg');
size(x);
x=imresize(x,[500 800]);
figure;
imshow(x);
title('original image');
z=rgb2hsv(x);       %extract the value part of hsv plane
v=z(:,:,3);
v=imadjust(v);
m = mean(v(:))
s=std(v(:))
k=-2;
value=m+ k*s;
temp=v;
for p=1:1:500
    for q=1:1:800
        pixel=temp(p,q);
        if(pixel>value)
            temp(p,q)=1;
        else
            temp(p,q)=0;
        end
    end
end
figure;
imshow(temp);
title('result by niblack');
% k=kittlerMet(g);
% figure;
% imshow(k);
% title('result by kittlerMet');

val2=m*(1+.1*((s/128)-1));
t2=v;
for p=1:1:500
for q=1:1:800
    pixel=t2(p,q);
    if(pixel>value)
        t2(p,q)=1;
    else
        t2(p,q)=0;
    end
end

end
figure;
imshow(t2);
title('result by sauvola');

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

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


2
Якщо це призначено для відповіді на запитання, поясніть, що ви робите та чому.
Метт Л.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.