Aumento de Contraste e Equalização de Histograma

O histograma de uma imagem digital com \(L \) possíveis níveis de intensidades em um intervalo \([0,G] \) é definido como a seguinte função discreta

\( h(r_k) = n_k \)

onde \(r_k \) é o \(k-esimo \) nível dentro do intervalo \([0,G] \) e \(n_k \) é o número de pixels na imagem cuja intensidade é \(r_k \). Geralmente o valor \(G \) é \(255 \), pois quase sempre trabalhamos com imagens em escalas de 8 bits. Contudo, esse valor pode ser \(65535 \) para imagens de 16 bits, \(1.0 \) para alguma representação de imagens que utiliza ponto flutuante, etc.

Muitas vezes precisamos trabalhar com histogramas normalizados, que são obtidos simplesmente dividindo-se todos elementos de \(h(r_k) \) pelo número total de pixels na imagem. Denotaremos essa transformação da seguinte maneira:

\( p(r_k) = \dfrac{h(r_k)}{n} = \dfrac{n_k}{n} \)

onde, \(k=0,1,2,\ldots, L-1 \). Dessa formulação é fácil reconhecer que \(p(r_k) \) é uma estimativa probabilística da ocorrência do nível de intensidade $r_k$.

Assumindo que os níveis de intensidades sejam quantidades contínuas e normalizadas no intervalo \([0,1] \), e chamando de \(p_r(r) \) a função densidade de probabilidade dos níveis. Supondo que realizamos a seguinte transformação dos níveis da imagem original para obter os níveis processados:

\( s = T(r) = \int_0^r p_r(w) dw \)

onde \(w \) é uma variável de integração qualquer. A função densidade de probabilidade dos níveis processados serão uniformes, isto é,

\(
p_s(s) = \left\{
\begin{array}{lcl}
1 & ~ & 0 \leq s \\
0 & ~ & otherwise
\end{array}
\right.
\)

Como imagens são quantidades discretas, nós trabalhamos com histogramas e realizamos a operação de equalização. Ou seja, realizamos o processo acima, mas sem considerarmos uma distribuição contínua. Assim, ao invés de utilizarmos a função densidade de probabilidade, trabalhamos com as probabilidades extraídas das ocorrências contadas no histograma:


\( s_k = T(r_k) = \sum_{j=0}^{k} p_r(r_j) = \sum_{j=0}^{k} \frac{n_j}{n} \)

para \(k = 0, 1, 2, \ldots, L-1 \), onde \(s_k \) é o valor de intensidade na saída, correspondendo ao valor da imagem original \(r_k \). Este processo é implementado na seguinte função:

def histeq(arr):
    """ Enhance contrast using histogram equalization
USAGE:
        [equalized] = histeq(arr)
 
INPUT:
    * arr: to be balanced
 
RETURN:
    * equalized: balanced
 
AUTHOR:
    * Pedro Garcia [sawp@sawp.com.br], http://www.sawp.com.br
 
LICENSE:
    * Creative Commons
      http://creativecommons.org/licenses/by-nc-nd/2.5/br/"""
 
    (hist, bin_edges) = histogram(arr.flatten(), 256, normed=True)
    cumsum_along_axis = hist.cumsum()
    cumsum_along_axis = 255.0 * cumsum_along_axis / cumsum_along_axis[-1]
    y = interp(arr.flatten(), bin_edges[:-1], cumsum_along_axis)
    y = y.reshape(arr.shape)
    return y

Como resultado, a transformação gera uma imagem em que os níveis de intensidade são igualmente distribuídos dentro do intervalo \([0,1] \). O resultado visual desta operação é uma imagem com maior contraste, conforme podemos visualizar nas figuras abaixo.


Original (parâmetro)

Equalizada (retorno)