O histograma de uma imagem em tons de cinza é uma medida estatística que indica o número de ocorrências de um determinado
nível de cinza na imagem. Na toolbox ia636 existe a função ia636:iahistogram
que calcula o histograma a partir de uma
imagem em níveis de cinza. Ela utiliza a função "bincount" do NumPy. Não é fácil desenvolver uma função em Python/NumPy
que seja eficiente para calcular o histograma. Uma implementação simples de entender que porém não é eficiente é a "iahistogram_eq" que está em ia636:iahistogram
.
É necessário fazer um laço explícito em todos os níveis de cinza e para contar quantas pixels possuem aquele nível de cinza.
No final da página do ia636:iahistogram
tem uma comparação de tempos das duas funções.
Veja a seguir o código Python/NumPy para se calcular e mostrar o histograma no Adessowiki. O histograma é um vetor unidimensional e é normalmente visualizado no Adessowiki utilizando a função "iaplot" que a prepara para ser mostrada via "adshow". As figuras abaixo mostram a imagem 'cameraman', juntamente com seu histograma.
In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
In [21]:
f = mpimg.imread('../data/cameraman.tif')
plt.imshow((f>40) & (f<150),cmap='gray')
Out[21]:
In [12]:
h = np.bincount(f.ravel())
plt.plot(h)
Out[12]:
In [11]:
print(f.min(),f.max())
print(len(h))
print(h)
print(h.max())
print(np.where(h==h.max()))
#adshow(ia.iaplot(h, ylabel='n. de pixels', xlabel='niveis de cinza'), 'histograma de f')
Analisando-se o histograma da imagem cameraman, observa-se que existe uma grande quantidade de pixels com valores escuros. Eles correspondem ao paletó do cameraman.
Ao se calcular o histograma de uma imagem, perde-se a informação da disposição espacial dos seus pixels. Veja por exemplo, se ordenarmos os pixels da imagem cameraman, o seu histograma continuará o mesmo: —
In [23]:
g = np.sort(f.ravel()).reshape(f.shape)
plt.imshow(g,cmap='gray')
#hg = ia.iahistogram(g)
#adshow(ia.iaplot(hg, ylabel='n. de pixels', xlabel='niveis de cinza'), 'histogram de f com pixels ordenados')
Out[23]:
Observe que visualizar a imagem de pixels ordenados é também uma boa forma de perceber a distribuição dos níveis de cinza de uma imagem. Neste caso, observe como existe uma transição razoavelmente abrupta entre a parte mais escura e mais clara. Isto corresponde ao vale no histograma, quanto mais largo for um vale, mais abrupta será a variação entre os níveis de cinza do vale.
Nota-se acima que um mesmo histograma existe para duas imagens. Apesar disto, o histograma é uma das medidas que pode caracterizar uma imagem. Muito métodos bens sucedidos de classificação de categorias de imagens são baseados nas informações de seu histograma.
Três outras curvas geradas a partir do histograma são importantes: o histograma acumulado, o histograma normalizado e o histograma acumulado normalizado. A normalização ocorre quando divide-se o histograma pelo número de pixels da imagem, fazendo com que a soma dos valores do histograma seja 1.0. O histograma acumulado é dado pela integral do histograma. Veja o cálculo destas três curvas:
In [24]:
hc = np.cumsum(h)
plt.plot(hc)
Out[24]:
In [27]:
hcn = hc.astype(float)/f.size
plt.plot(hcn)
Out[27]:
In [25]:
hn = h.astype(float)/f.size
plt.plot(hn)
Out[25]:
A partir do histograma é possível calcular diversas estatísticas da imagem, com a vantagem de não precisar
varrer novamente a imagem para o seu cálculo. Veja a função ia636:iah2stats
que faz o cálculo das seguintes
medidas: média, variância, obliquidade, curtose, moda mediana, percentil e entropia.
http://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html#numpy.histogram histogram
http://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html#numpy.bincount bincount
ia636:iahistogram
Função iahistogram`ia636:iaplot
Plot no Adessowikihttp://en.wikipedia.org/wiki/Histogram Histogram - Wikipedia
In [ ]: