Limiarização

1 Introdução

       
Limiarização é um processo de segmentação de imagens que se baseia na diferença dos níveis de cinza que compõe diferentes objetos de uma imagem. A partir de um limiar estabelecido de acordo com as características dos objetos que se quer isolar, a imagem pode ser segmentada em dois grupos: o grupo de pixels com níveis de cinza abaixo do limiar e o grupo de pixels com níveis de cinza acima do limiar. Em uma imagem limiarizada, atribui-se um valor fixo para todos os pixels de mesmo grupo.

Logo, uma imagem g(x, y) limiarizada pode ser definida como:

Imagem limiarizada.
Equação 1

A imagem g(x, y) será binária, ou seja, terá somente dois valores possíveis para cada pixel.

Alternativamente, pode-se isolar apenas um dos grupos separados pelo limiar, mantendo-se os valores originais dos pixels restantes. Por exemplo, os níveis de cinza de uma imagem f(x, y) podem ser saturados pela seguinte transformação:

Saturação
Equação 2

A limiarização também pode ser aplicada para truncar os valores de níveis de cinza de uma imagem, de modo que os valores de g(x, y) sejam limitados ao intervalo [0, T].

Equação 3

2 Implementação

A biblioteca OpenCV oferece duas funções que permitem limiarizar uma imagem. A função 
adaptiveThreshold() gera uma imagem binária, utilizando um limiar adaptativo. A função threshold() utiliza um limiar fixo dado, e pode gerar uma imagem binária, saturada ou truncada, conforme especificado por parâmetro.

A implementação de uma função genérica de limiarização é apresentada abaixo. A função é chamada especificando-se uma imagem de entrada, o valor do limiar e os valores de cinza que serão atribuídos aos pixels de cada grupo da segmentação. Todos os valores de cinza são dados no intervalo [0, 1], onde 0 representa preto puro e 1 representa branco puro.
01 /* Limiariza uma imagem em escala de cinza, trocando os valores menores ou 
02  *  iguais a 'threshold' para 'below', e os demais valores para 'above'.
03  * A macro UNCHANGED pode ser utilizada para 'below' ou 'above', caso seja
04  *  desejado que os valores não sejam alterados abaixo ou acima do limiar.
05  */
06 void
07 thresh(IplImage *image, float threshold, float below, float above)
08 {
09     int x, y;
10     int offset;
11     unsigned char uc_threshold, uc_below, uc_above;
12 
13     uc_threshold = (unsigned char) (threshold * 255.0);
14     uc_below = (unsigned char) (below * 255.0);
15     uc_above = (unsigned char) (above * 255.0);
16 
17     for (y = 0; y < image->height; y++) {
18         for (x = 0; x < image->width; x++) {
19             offset = y * image->widthStep + x;
20 
21             if ((unsigned char) image->imageData[offset] <= uc_threshold) {
22                 if (below != UNCHANGED)
23                     image->imageData[offset] = uc_below;
24             }
25             else {
26                 if (above != UNCHANGED)
27                     image->imageData[offset] = uc_above;
28             }
29         }
30     }
31 }
Nas linhas 13-15, os valores de nível de cinza são convertidos para a representação interna utilizada pela estrutura IplImage. No restante da função, o nível de cinza de cada pixel da imagem é comparado ao limiar, e alterado de acordo com o resultado da comparação. Nesta implementação, a macro UNCHANGED pode ser utilizada para indicar que um grupo de pixels não deve ser alterado, o que permite diferentes combinações de saturação e truncamento.

Código de exemplo para utilização desta função: thresh.c.

3 Testes

Utilizando a função thresh() implementada, podemos aplicar a limiarização na imagem abaixo, cujo histograma é apresentado em seguida.


 
Imagem em escala de cinza
 
Histograma de imagem em escala de cinza


O histograma da imagem mostra que há uma grande quantidade de pixels com níveis de cinza entre 0.6 e 0.8.

Limiarizando a imagem com base na equação 1, utilizando T = 0.6, obtemos a seguinte imagem binária:

Limiarização T = 6.0

Utilizando o mesmo valor para T, desta vez na equação 2, obtemos uma imagem saturada:


E finalmente, utilizando a equação 3, os níveis de cinza acima do limiar 0.6 são truncados para este valor:

Nível de cinza truncado

4 Análise de Desempenho

A imagem utilizada como teste possui dimensões 2592x1944
. A tabela a seguir exibe o tempo gasto para cada tipo de limiarização.

 Tipo de limiarização
 Tempo de processamento (ms)
 Binária 13
 Saturação 11
 Truncamento 12

Levando-se em consideração a margem de erro para medição de tempo em um computador comum, os valores encontrados não são expressivos, mesmo para uma imagem relativamente grande. Uma melhor análise de desempenho poderia ser realizada processando uma sequência de imagens.

Comments