Quali sono i migliori algoritmi per il soglia delle immagini dei documenti in questo esempio?


31

Sto cercando di implementare vari algoritmi di binarizzazione sull'immagine mostrata: inserisci qui la descrizione dell'immagine

Ecco il codice:

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

% Ora ridimensioniamo le immagini in modo che il lavoro computazionale diventi più facile per noi in seguito.

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);

% ora troviamo la deviazione media e standard richiesta per gli algoritmi niblack e% sauvola

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

% implementando l'algoritmo di soglia niblack:

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');

% implementazione algoritmo di soglia sauvola:

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

fine

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

I risultati che ho ottenuto sono i seguenti: inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Come puoi vedere le immagini risultanti sono degradate nei punti più scuri. Qualcuno potrebbe suggerire come ottimizzare il mio risultato ??


1
È possibile utilizzare le informazioni sul colore per eliminare lo sfondo anziché solo la luminosità?
endolith

Rispettato signore / signora. Sto facendo un progetto sull'elaborazione delle immagini. Sono un interessante concetto di binarizzazione. Per favore controlla e correggi la codifica ... Prendo la codifica ed eseguo il programma. e un altro è Errore in msp (riga 31) k = kittlerMet (g); .. Come risolverlo ... Correggi la codifica ...
muthu

Risposte:


49

L'immagine non ha una luminosità uniforme, quindi non dovresti lavorare con una soglia uniforme. Hai bisogno di una soglia adattiva. Questo può essere implementato preelaborando l'immagine per rendere la luminosità più uniforme sull'immagine (codice scritto in Mathematica, dovrai implementare la versione Matlab per te):

Un modo semplice per uniformare la luminosità è rimuovere il testo effettivo dall'immagine usando un filtro di chiusura:

white = Closing[src, DiskMatrix[5]]

inserisci qui la descrizione dell'immagine

La dimensione del filtro deve essere scelta più grande della larghezza del tratto del carattere e più piccola della dimensione delle macchie che stai cercando di rimuovere.

EDIT: nei commenti mi è stato chiesto di spiegare cosa fa un'operazione di chiusura. È una dilatazione morfologica seguita da un'erosione morfologica . La dilatazione essenzialmente sposta l'elemento strutturante in ogni posizione dell'immagine e seleziona il pixel più luminoso sotto la maschera, quindi:

  • rimuovendo le strutture scure più piccole dell'elemento strutturante
  • restringendo le strutture scure più grandi della dimensione dell'elemento strutturante
  • allargando le strutture luminose

L'operazione di erosione fa l'opposto (seleziona il pixel più scuro sotto all'interno dell'elemento strutturante), quindi se lo applichi sull'immagine dilatata:

  • le strutture scure che sono state rimosse perché più piccole dell'elemento strutturante sono ancora sparite
  • le strutture più scure che erano rimpicciolite vengono nuovamente ingrandite alla loro dimensione originale (anche se la loro forma sarà più liscia)
  • le strutture luminose sono ridotte alle dimensioni originali

Quindi l'operazione di chiusura rimuove piccoli oggetti scuri con solo piccole modifiche a oggetti scuri più grandi e oggetti luminosi.

Ecco un esempio con diverse dimensioni degli elementi strutturanti:

inserisci qui la descrizione dell'immagine

All'aumentare della dimensione dell'elemento strutturante, sempre più personaggi vengono rimossi. A raggio = 5, tutti i caratteri vengono rimossi. Se il raggio aumenta ulteriormente, vengono rimosse anche le macchie più piccole:

inserisci qui la descrizione dell'immagine

Ora dividi semplicemente l'immagine originale per questa "immagine bianca" per ottenere un'immagine di luminosità (quasi) uniforme:

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

inserisci qui la descrizione dell'immagine

Questa immagine può ora essere binarizzata con una soglia costante:

Binarize[whiteAdjusted , 0.6]

inserisci qui la descrizione dell'immagine


5
Wow! Questo è davvero fantastico! Enorme +1!
Phonon,

@nikie +1 Molto bello - cosa intendi esattamente con la chiusura del filtro deve essere "scelto più grande del tratto del carattere"? Larghezza o lunghezza di una lettera? Inoltre, cosa sta facendo "davvero" un filtro di chiusura? Grazie!
Spacey,

1
@Mohammad: ho aggiunto una piccola spiegazione alla mia risposta. E sì, queste sono operazioni non lineari. L'intestazione comune è l'elaborazione dell'immagine morfologica.
Niki Estner,

1
@nikie Non importa, il bianco è il massimo, non il nero. :-)
Spacey

1
@gdelfino: di solito cerco di evitarlo usando una maschera abbastanza grande, e uso Clip[ImageData[white],{eps,Infinity}]dove eps è un numero piccolo, per sicurezza.
Niki Estner,

6

La risposta di Nikie sembra la migliore e sembra anche funzionare e produrre risultati. Quindi è un chiaro vincitore.

Tuttavia, solo per la documentazione ho aggiunto un altro riferimento, che potrebbe essere molto veloce.

Questa tecnica si chiama Soglia adattiva che non richiede l' apprendimento esplicito del background.

In sostanza, invece di trovare la soglia globale più adatta , possiamo partizionare l'immagine in una finestra locale (diciamo circa 7x7 o appropriata) e trovare soglie che cambiano mentre la finestra attraversa.

Il riferimento seguente descrive in dettaglio il metodo esatto. http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm

Questo metodo sarebbe relativamente più veloce dal punto di vista computazionale.


Queste due cose non sono essenzialmente le stesse? Vale a dire stimare la media locale del segnale prima della soglia?
Maurits,

1
@Maurits Sembra che le differenze principali siano l'ordinamento e le statistiche utilizzate. Ad esempio, negli operatori di apertura / chiusura (che sono costituiti da dilatazione ed erosione ma in un ordine diverso), una finestra viene scansionata raster e viene acquisito max. (Tra le altre cose). Tuttavia, nella soglia adattativa si può prendere la media / mediana invece del max.
Spacey,

OP lo ha chiesto anche su SO , a cui ho risposto. Ma in linea di principio, non penso che ci sia alcuna differenza tra le risposte, si sta sempre stimando le statistiche locali. Se si esegue il limite adattativo, si impara anche lo sfondo nel processo.
Maurits,

6

Un altro modo di usare un filtro passa-banda (in MATLAB). Giocare con la differenza dei parametri gaussiani può dare risultati migliori. Il processo consiste sostanzialmente nel filtrare il filtro passa-banda dell'immagine per rimuovere i BLOB di sfondo a bassa frequenza, normalizzare a [0,1] richiesto per il comando 'graythresh', immagine di soglia.

Carica immagine e converti in scala di grigi doppia:

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

inserisci qui la descrizione dell'immagine

Filtra usando la differenza del kernel gaussiano e normalizza:

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

inserisci qui la descrizione dell'immagine

Calcola la soglia e crea 010101:

T = J > graythresh(J);

inserisci qui la descrizione dell'immagine


4

Questo è un buon codice Matlab per la soglia adattativa: http://www.mathworks.com/matlabcentral/fileexchange/8647-local-adaptive-thresholding


Argh! Richiede tuttavia la casella degli strumenti di elaborazione delle immagini. : - /
Spacey

Infatti. Scusa se non ce l'hai. DIPImage è un Tolbox immagine gratuito per Matlab. diplib.org/documentation Ha alcuni metodi per il soglia (controllare la sezione di segmentazione) e puoi anche fare tutte le operazioni morfologiche come la chiusura. Lo sviluppatore ha anche un blog cb.uu.se/~cris/blog/index.php/archives/tag/matlab
MyCarta

0

Proverò questa codifica, ma non ho una risposta corretta ...

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');

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


2
Se questo ha lo scopo di rispondere alla domanda, ti preghiamo di spiegare cosa stai facendo e perché.
Matt L.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.