Sunteți pe pagina 1din 12

1

Mtodos de binarizao de Wolf e NICK


ARAMIS HORNUNG MORAES
PUC-PR Pontifcia Universidade Catlica do Paran
https://plus.google.com/103791949210339737668/
Resumo: Neste artigo so apresentadas as tcnicas de binarizao local de Wolf e NICK. A tcnica de
binarizao local NICK visa alcanar melhor resultado de binarizao, especificamente, em documentos
antigos. A tcnica de binarizao local NICK tem sido inspirado pelo mtodo de limiarizao de Niblack e tem
mostrado a sua robustez e eficcia quando avaliado com imagens de baixa qualidade de documentos antigos.
Palavras-chave: Documentos antigos, binarizao local, Wolf, NICK, Niblack.

Introduo
A importncia de bibliotecas digitais para recuperao e conservao da informao no pode ser negada. Os livros
histricos possuem um conhecimento inestimvel, mas muito demorado para pesquisar as informaes necessrias
neles. Diferentes mtodos foram desenvolvidos para facilitar a procura por informaes, como destacar palavras,
reconhecimento ptico de letras etc. Apesar de vrios trabalhos terem sido feitos nesta rea, ainda existe um convidativo
e desafiador campo de pesquisa. Principalmente porque os resultados obtidos at ento no so satisfatrios para grande
volume de dados, especialmente se o documento analisado estiver em relativo estado de degradao.
Uma das etapas para a digitalizao destes documentos a binarizao de suas imagens, ou seja, a separao do das
letras em relao ao plano de fundo. A binarizao de uma imagem de texto deve nos dar, num caso ideal, o texto em
preto no primeiro plano com um pouco de rudo e um fundo branco. Apesar de diferentes mtodos de binarizao j
existirem na literatura, eles no do resultados perfeitos para todos os tipos de documentos. Alguns algoritmos podem
funcionar melhor para um tipo de documento, onde h marcas de amassados embora para outros casos possam dar maus
resultados onde existem variaes extremamente baixa de intensidade das cores.
Este artigo tem como foco mostrar duas tcnicas de binarizao baseados no mtodo Niblack, so elas as tcnicas
de binarizao local de Wolf e NICK. A tcnica de binarizao local de Niblack ser brevemente discutida na seo 2 a
seguir. Na seo 3 ser descrita a tcnica de binarizao de Wolf e finalmente na seo 4 descrita a tcnica de
binarizao NICK.

Tcnica de binarizao local de Niblack


Este o algoritmo no qual foram baseadas as tcnicas de Wolf e NICK, por isso importante analis-lo. A tcnica
de Niblack calcula um limiar de pixel deslizando uma janela retangular na imagem em nvel de cinza. O clculo do
limiar baseado no local da mdia m e o desvio padro s de todos os pixels da janela e dado pela equao 1 a seguir:

TNiblack = m + k s

TNiblack = m + k

pi2

NP

m 2 Equao 1

Tcnica de Binarizao de Wolf


Para tratar dos problemas do mtodo de binarizao de outro algoritmo de limiarizao chamado de Sauvola, Wolf
props a normalizao do contraste e a mdia dos valores de cinza com a seguinte notao:

TWolf = (1 k ) m + k M + k

s
( m M ) Equao 2
R

2
Onde k fixado como 0.5, M o valor mnimo de cinza da janela e R definido como o padro mximo do valor
cinzento do desvio obtido sobre todos as regies locais adjacentes (janelas), m a mdia do valor de cinza da janela e s
o desvio padro da janela.
Este mtodo na maioria dos casos supera outros mtodos de binarizao como o mtodo de Sauvola e Niblack. No
entanto, uma degradao observada, se houver uma mudana brusca nas cores de fundo da imagem na escala de cinza.
Isso acontece devido ao fato dos valores M e R serem calculados da imagem inteira. Ento mesmo um pequeno rudo
poderia influencia significativamente os valores M e R, assim causando falsos resultados para binarizao.
4

Mtodo de Binarizao NICK


Baseado no mtodo de binarizao de Niblack, a tcnica NICK definido pela seguinte notao:

TNICK = m + k

p i2 m 2
NP

Equao 3

onde,
k o fator Niblack
m = mdia do valor de cinza na janela
pi = valor de cinza do pixel
NP = nmero de pixels
5

Experimentos

Nos experimentos efetuados com as tcnicas de Nick e de Wolf foram utilizados apenas imagens em nveis de
cinza de documentos antigos, manuscritos ou cheques, pois a principal aplicao destas tcnicas so limiarizar
documentos antigos e danificados. Na Figura 01 o resultado obtido foi interessante para ambas as tcnicas, pois um
caso bem simples, onde a informao original j se apresenta bem destacada.

Figura 01 Experimento em que ambas as tcnicas apresentam resultados interessantes. A imagem original possui 3 classes.
Apesar das duas tcnicas apresentarem resultados aparentemente semelhantes, cada uma possui uma peculiaridade que se
destaca para algumas situaes. Pode-se observar nas figuras 02 e 03 os pontos fortes da tcnica de Nick.

Figura 02 Experimento em que a tcnica de Nick se destaca. Aqui a tcnica descarta as escritas no verso do papel. A imagem
original possui vrias classes

Figura 03 Outro experimento em que a tcnica de Nick obteve um excelente resultado. Nesse caso a tcnica conseguiu descartar
por completo a mancha no papel. A imagem original possui apenas uma classe.

Nos experimentos feitos nas figuras 02 e 03 podemos perceber que a tcnica de Nick menos sensvel em
relao as escalas de cinza mais claras. Desta forma a tcnica de Nick destaca apenas os detalhes mais escuros da
imagem, descartando na maioria das vezes o que seriam defeitos no documento, como manchas ou letras no verso da
folha. Entretanto, nem sempre a informao mais importante do documento se encontra nos nveis mais escuros de
cinza. Nestas situaes a tcnica de Nick pode deixar de fora parte da informao na imagem que nos interessa. As
figuras 04 e 05 mostram casos em que a tcnica de Wolf mantm essas informaes em nveis mais claros de cinza.

Figura 04 Neste experimento, a tcnica de Wolf consegue um resultado mais satisfatrio em relao a tcnica de Nick pois o texto
se mantm inteiro na imagem limiarizada. A imagem original deste experimento aparentemente possui uma classe

Figura 05 Outro caso em que a tcnica de Wolf se destaca em relao a tcnica de Nick. A tcnica de Wolf mantm algumas
informaes. A Imagem original possui mais de duas classes.

Nos experimentos realizados nas figuras 04 e 05, a tcnica de Wolf se destaca em relao a tcnica de Nick,
pois analisa de forma mais sensvel a imagem, considerando os pixeis em nveis de cinza mais claros, ao contrrio da
tcnica de Nick que considera os pixeis mais escuros da imagem.
Na Figura 04 a tcnica de Nick descarta onde a escrita fica um pouco mais fraca, apagando algumas palavras no
documento, perdendo assim parte da informao. Na Figura 05 as informaes manuscritas so dificilmente interpretadas a partir da
imagem limiarizada pela tcnica de Nick, mas se apresentam melhor na imagem limiarizada pela tcnica de Wolf.

Apesar de em certos casos uma tcnica ser melhor que a outra, ambas apresentam resultados interessantes de
forma geral.

Concluses
Ambas as tcnicas de Wolf e de Nick so excelentes para a maioria dos casos de limiarizao de documentos.
Elas so bastante semelhantes, mas cada uma possui sua peculiaridade, que por coincidncia so complementares entre
elas. A tcnica de limiarizao de Wolf mais sensvel a nveis de cinza mais claros, e consegue detectar detalhes que
importam em uma imagem. Esses detalhes geralmente so manuscritos, ou letras escritas em tons mais claros de cinza.
A tcnica de Nick possui uma caracterstica inversa a de Wolf pois destaca o contedo mais escuro da imagem
e descarta os tons mais claros de cinza, ignorando assim o que seria na maioria das vezes, defeitos no papel, ou
informaes irrelevantes, como as escritas no verso da folha.
No final, ambas apresentam resultados relativamente interessantes para a maioria das imagens experimentadas.

5
7

Fontes

a) void

CPDIBase::LimiarWolf()

void CPDIBase::LimiarWolf() // Aramis Hornung Moraes


{
/* Primeira reviso - 20/09/2014

Aramis Hornung Moraes */

register int i, j; // coordenadas intermediarias para acessar pixels vizinhos

// valores das coordenadas intermediarias para acessar pixels vizinhos na janela


int Val_i = 1,// valor PARA acessar pixels VIZINHOS nas LINHAS VIZINHAS
Val_j = 1; // valor PARA acessar pixels VIZINHOS nas COLUNAS VIZINHAS
long int row = 0, col = 0; //COORDENADAS DOS PIXELS

const int height = (long int) GetHeight(); //declarao e atribuio de valor mximo de linhas
const int width = (long int) GetWidth(); //declarao e atribuio de valor mximo de colunas
BYTE *lpTemp = lpBits; //cpia do buffer de entrada

int num_pixels_img = height * width;

// variveis auxiliares para calculo da limiar de WOLF

BYTE *buffer_media_cinza_janela =

new BYTE [num_pixels_img];

BYTE *buffer_min_val_cinza_janela =

new BYTE [num_pixels_img];

BYTE *buffer_des_padrao_janela =

new BYTE [num_pixels_img];

BYTE *buffer_limiarizacao =

new BYTE [num_pixels_img];

BYTE maior_desv_padrao_imagem;

BYTE Pixel_Vizinho = 0; //definir antes do for

//

I)

Preenche buffer da media de cinza por janela

// antes vamos inicializar a matriz


for(row = 0; row < height; row = row++) // VARREDURA DAS LINHAS DA IMAGEM
for(col = 0; col < width; col++) // VARREDURA DAS COLUNAS DA IMAGEM
buffer_media_cinza_janela[row * width + col] = 0;

for(row = 1; row < height-1; row++) // VARREDURA DAS LINHAS DA IMAGEM


{
for(col = 1; col < width-1; col++) // VARREDURA DAS COLUNAS DA IMAGEM
{

6
//long double janela[9];
long double media = 0;

//INICIALIZACAO ANTES DOS CALCULOS

int n = (((2*Val_j)+1)*((2*Val_j)+1)); // variavel da de numero pixel da janela


quadrada

for(j = -Val_j; j<= Val_j; j++)


{
for(i = -Val_i; i<= Val_i; i++)
{
// ACESSO AO valor do nvel de cinza do PIXEL VIZINHO nas coordenadas
(lin+j) e (col+i)
media += *lpTemp + (row+j)*width+(col+i);
//janela[n] = Pixel_Vizinho; n++;
}
}

media = media/n;

buffer_media_cinza_janela[row * width + col] = media; // grava a mdia da janela no


buffer apropriado
}
}

Pixel_Vizinho = 0;
//

II)

Preenche buffer do valor minimo de cinza na janela

// antes vamos inicializar a matriz


for(row = 0; row < height; row = row++) // VARREDURA DAS LINHAS DA IMAGEM
for(col = 0; col < width; col++) // VARREDURA DAS COLUNAS DA IMAGEM
buffer_min_val_cinza_janela[row * width + col] = 255;

BYTE min = 1000;


for(row = 1; row < height-1; row++) // VARREDURA DAS LINHAS DA IMAGEM
{
for(col = 1; col < width-1; col++) // VARREDURA DAS COLUNAS DA IMAGEM
{
min = *lpTemp + row*width+col; //INICIALIZACAO COM VALOR DO PIXEL

for(j = -Val_j; j<= Val_j; j++)


{
for(i = -Val_i; i<= Val_i; i++)
{

7
// ACESSO AO valor do nvel de cinza do PIXEL VIZINHO nas coordenadas
(lin+j) e (col+i)
Pixel_Vizinho = *lpTemp + (row+j)*width+(col+i);
if(*lpTemp + (row+j)*width+(col+i)< min)
min = Pixel_Vizinho;
}
}
buffer_min_val_cinza_janela[row*width+col] = min;
}
}

//

III)

Preenche buffer do desvio padrao de cinza na janela

// antes vamos inicializar a matriz


for(row = 0; row < height; row = row++) // VARREDURA DAS LINHAS DA IMAGEM
for(col = 0; col < width; col++) // VARREDURA DAS COLUNAS DA IMAGEM
buffer_des_padrao_janela[row * width + col] = 0;

for(row = 1; row < height-1; row++) // VARREDURA DAS LINHAS DA IMAGEM


{
for(col = 1; col < width-1; col++) // VARREDURA DAS COLUNAS DA IMAGEM
{
long int indice_pixel_corrente = row*width+col;
long double somatorio = 0;

int n = (((2*Val_j)+1)*((2*Val_j)+1)); // variavel da de numero pixel da janela


quadrada

for(j = -Val_j; j<= Val_j; j++)


{
for(i = -Val_i; i<= Val_i; i++)
{
// ACESSO AO valor do nvel de cinza do PIXEL VIZINHO nas coordenadas
(lin+j) e (col+i)
Pixel_Vizinho = *lpTemp + (row+j)*width+(col+i);

somatorio
buffer_media_cinza_janela[indice_pixel_corrente])*(Pixel_Vizinho
buffer_media_cinza_janela[indice_pixel_corrente]);

+=(Pixel_Vizinho

}
}
buffer_des_padrao_janela[row * width + col] = sqrt(somatorio/n); // grava
}

8
}

// Define maior valor de desvio padro


maior_desv_padrao_imagem = 0;
for(int i = 0; i < num_pixels_img; i ++)
{
if(maior_desv_padrao_imagem < buffer_des_padrao_janela[i])
maior_desv_padrao_imagem = buffer_des_padrao_janela[i];
}

//

IV)

Calcula a matriz de limiar

//"varredura" de todos os pixels


for (row = 0; row < height; row++)
{
for (col = 0; col < width; col++)
{
//valor de cinza do pixel
//long int pixel_val_cinza = lpTemp[row * bmWidthBytes + col];
float

k = 0.5; /* pode variar */

BYTE

m = buffer_media_cinza_janela[row * width + col];

BYTE

M = buffer_min_val_cinza_janela[row * width + col];

BYTE

s = buffer_des_padrao_janela[row * width + col];

BYTE

R = maior_desv_padrao_imagem;

buffer_limiarizacao[row * width + col]

(1-k)

*(s/R*(m-M));

}
}

// Limearizar a imagem de saida


int

data;

lpTemp = lpBits;
for (row = 0; row < (int) GetHeight(); row++, lpTemp += bmWidthBytes)
{
for (col = 0; col < (int) GetWidth(); col++)
{
data = lpTemp[col];
//lpTemp[col] = (data < buffer_limiarizacao[row * bmWidthBytes + col]) ? 0 : 255; //
Arrumado
lpTemp[col] = (data < buffer_limiarizacao[col]) ? 0 : 255;
}
}

delete buffer_media_cinza_janela;
delete buffer_min_val_cinza_janela;
delete buffer_des_padrao_janela;
delete buffer_limiarizacao;
}

b)

void CPDIBase::LimiarNick()

void CPDIBase::LimiarNick() // Aramis Hornung Moraes


{
//Primeira reviso - 20/09/2014

Aramis Hornung Moraes

register int i, j; // coordenadas intermediarias para acessar pixels vizinhos

// valores dao tamanho da janela em pixel


int Val_i = 1, // valor PARA acessar pixels VIZINHOS nas LINHAS VIZINHAS
Val_j = 1; // valor PARA acessar pixels VIZINHOS nas COLUNAS VIZINHAS

long int row = 0, col = 0; //COORDENADAS DOS PIXELS

const int height = (long int) GetHeight(); //declarao e atribuio de valor mximo de linhas
const int width = (long int) GetWidth(); //declarao e atribuio de valor mximo de colunas
BYTE *lpTemp = lpBits; //cpia do buffer de entrada

int num_pixels_img = height * width;

BYTE *buffer_media_cinza_janela =

new BYTE [num_pixels_img];

BYTE *buffer_limiarizacao =

new BYTE [num_pixels_img];

BYTE maior_desv_padrao_imagem;

BYTE Pixel_Vizinho = 0; //definir antes do for

//

I)

Preenche buffer da media de cinza por janela

// antes vamos inicializar a matriz


for(row = 0; row < height; row++) // VARREDURA DAS LINHAS DA IMAGEM
for(col = 0; col < width; col++) // VARREDURA DAS COLUNAS DA IMAGEM
buffer_media_cinza_janela[row * width + col] = 0;

for(row = 1; row < height-1; row++) // VARREDURA DAS LINHAS DA IMAGEM


{
for(col = 1; col < width-1; col++) // VARREDURA DAS COLUNAS DA IMAGEM
{
//long double janela[9];
long double media_viz = 0;
int n = (((2*Val_j)+1)*((2*Val_j)+1)); // variavel da de numero pixel da janela
quadrada

for(j = -Val_j; j<= Val_j; j++)


{

1
for(i = -Val_i; i<= Val_i; i++)
{
// ACESSO AO valor do nvel de cinza do PIXEL VIZINHO nas coordenadas
(lin+j) e (col+i)
Pixel_Vizinho = (*lpTemp + (row+j)*width+(col+i));
media_viz += Pixel_Vizinho;
//janela[n] = Pixel_Vizinho; n++;
}
}
//faz mdia da janela
media_viz = (media_viz/n);
buffer_media_cinza_janela[row * width + col] = media_viz; // grava a mdia da janela
no buffer apropriado
}
}

Pixel_Vizinho = 0; //definir antes do for


unsigned long long int somatorio = 0;
for (row = 0; row < height; row++)
{
for (col = 0; col < width; col++)
{
Pixel_Vizinho = lpTemp[row * width + col];
somatorio +=

(Pixel_Vizinho * Pixel_Vizinho);

}
}

//

II)

Calcula a matriz de limiar

//"varredura" de todos os pixels


for (row = 0; row < height; row++)
{
for (col = 0; col < width; col++)
{
float

k = 0.5; // pode variar

BYTE

m = buffer_media_cinza_janela[row * width + col];

BYTE

R = maior_desv_padrao_imagem;

long int NP = num_pixels_img;

1
buffer_limiarizacao[row * width + col]
((somatorio - (m*m))/NP));

sqrt((double)

}
}

// Limeariza a imagem de saida


int

data;

lpTemp = lpBits;
for (row = 0; row < (int) GetHeight(); row++, lpTemp += bmWidthBytes)
{
for (col = 0; col < (int) GetWidth(); col++)
{
data = lpTemp[col];
lpTemp[col] = (data < buffer_limiarizacao[col]) ? 0 : 255;
}
}
delete buffer_media_cinza_janela;
delete buffer_limiarizacao;

Referncias

Khurram Khurshid, Imran Siddiqi, Claudie Faure, Nicole Vincent, Comparison of Niblack inspired Binarization methods for ancient
documents, Document Recognition and Retrieval XVI, Proc. of SPIE-IS&T Electronic Imaging, SPIE 2009 Vol. 7247, p1-9

S-ar putea să vă placă și