Em um artigo de jornal de 1911, o editor Tess Flanders foi citado dizendo:
Use uma imagem. Vale mil palavras.
Portanto, não há dúvida de que as imagens desempenham um papel importante em nossas comunicações – não apenas fotografias gerais, mas também imagens especializadas, como ressonâncias magnéticas ou ultrassons.
Podemos obter fotos através de diferentes dispositivos de aquisição. Por exemplo, imagens de melanoma (câncer de pele) são recuperadas usando um dermatoscópio. Tiramos fotos de nós mesmos ou de amigos usando uma câmera digital ou um smartphone. Às vezes, porém, notamos alguns problemas em nossas fotos, como desfoque por exemplo, que pode ser devido ao dispositivo de aquisição utilizado.
Mas, o que fazer neste caso? Você recebeu algumas imagens médicas para analisar e não tem a opção de refazer essas imagens. Mesmo que você retome uma imagem, a resolução que você vê não mudará, nem quaisquer outros problemas que você enfrentar. Processamento de imagem entra em jogo em tais situações.
processamento de imagem: A análise e manipulação de uma imagem digitalizada, especialmente para melhorar a sua qualidade. — Dicionários Oxford
“Imagem digitalizada” aqui se refere ao fato de que a imagem é processada por um computador. Obter o computador neste jogo significa usar uma linguagem de programação.
Neste tutorial, mostrarei como podemos usar a linguagem de programação Python para executar tarefas de processamento de imagem em uma imagem.
scikit-imagem
A biblioteca que vamos usar para realizar nossas tarefas de processamento de imagem é scikit-image
. De acordo com o artigo scikit-image: processamento de imagens em Python:
scikit-image é uma biblioteca de processamento de imagens que implementa algoritmos e utilitários para uso em aplicações de pesquisa, educação e indústria. Ele é lançado sob a licença liberal de código aberto Modified BSD, fornece uma API bem documentada na linguagem de programação Python e é desenvolvido por uma equipe internacional ativa de colaboradores.
A primeira coisa que precisamos fazer é instalar scikit-image
. As instruções para instalar a biblioteca podem ser encontradas na página de download, e neste tutorial mostrarei como instalar a biblioteca em uma máquina Mac OS X, pois é isso que estou usando atualmente ao escrever este tutorial.
Como scikit-image
é uma biblioteca externa, a primeira coisa que temos que fazer é instalar aquela biblioteca. Para isso, usarei o pip, que é (baseado na Wikipedia):
Um sistema de gerenciamento de pacotes usado para instalar e gerenciar pacotes de software escritos em Python. Muitos pacotes podem ser encontrados no Python Package Index (PyPI).
Você pode seguir as etapas mencionadas no Guia do usuário do Python Packaging para instalar pip
mas se tiver Python 2.7.9
e superior, ou Python 3.4
e superior, você já tem pip
!
scikit-image
now pode ser simplesmente instalado digitando o seguinte comando:
pip install scikit-image
Agora temos a biblioteca instalada e pronta para se divertir com o processamento de imagens!
A imagem de teste que usaremos neste tutorial é uma ilustração de pizzaria. Vá em frente e faça o download, ou simplesmente use a imagem de sua escolha. A imagem tem a seguinte aparência:



Dimensões de uma imagem
Às vezes precisamos saber as dimensões de uma imagem (mais sobre isso na seção de filtragem). Uma vez que carregamos a imagem em nossa memória de um arquivo usando o imread()
método, podemos obter facilmente as dimensões da imagem com a ajuda de shape
atributo.
A razão pela qual esta técnica funciona é porque as imagens no scikit-image
módulo são representados por NumPy
matrizes. Aqui está um exemplo:
from skimage import io img = io.imread('baboon.png') # Outputs: (512, 512, 3) print(img.shape) # Outputs: 786432 print(img.size)
O atributo shape nos dá uma tupla onde o primeiro elemento é a altura da imagem, o segundo elemento é a largura da imagem e o terceiro elemento representa o número de canais. No nosso caso, o babuíno.png image tem três canais para valores de vermelho, verde e azul, então obtivemos o valor 3.
Aqui está um exemplo que carrega outra imagem:
from skimage import io img = io.imread('pizzeria.png') # (1271, 3200, 3) print(img.shape) # 12201600 print(img.size)
Você também pode carregar suas imagens em tons de cinza, definindo o valor do segundo parâmetro as_gray
no imread()
função a ser False
. o size
atributo nos diz o número de elementos na matriz. No caso de imagens em tons de cinza, esse valor é igual ao número de pixels da imagem. Aqui está um exemplo:
from skimage import io img = io.imread('pizzeria.png', as_gray=True) # Outputs: (1271, 3200) print(img.shape) # Outputs: 4067200 print(img.size)
Manipulando Pixels Individuais
Você pode modificar facilmente pixels individuais de qualquer imagem carregada usando a biblioteca scikit-image. Existem algumas convenções que devem ser mantidas em mente.
Ao acessar diretamente os pixels de uma imagem, o primeiro valor indica o número da linha e os segundos valores indicam o número da coluna. A origem ou a posição que corresponde a img[0, 0]
é o canto superior esquerdo da imagem. Você pode tornar o pixel na 200ª linha e 200ª coluna azul usando a linha img[200, 200] = [0, 0, 255]
.
Também é possível modificar um conjunto de pixels juntos. Aqui está um exemplo que adiciona uma borda vermelha à nossa imagem.
from skimage import io img = io.imread('pizzeria.png') # First 50 Rows img[:50,0] = [255, 0, 0] # First 50 Columns img[:,:50] = [255, 0, 0] # Last 50 Rows img[-50:,0] = [255, 0, 0] # Last 50 Columns img[:,-50:] = [255, 0, 0] io.imsave('red-border.png', img)
Este é o resultado:



Cor para escala de cinza
Nesta seção, gostaríamos de converter a imagem original colorida da Pizzaria em uma imagem 2D em tons de cinza (preto e branco). Isso pode ser feito simplesmente usando o seguinte script:
from skimage import io img = io.imread('pizzeria.png', as_gray=True) io.imsave('pizzeria-gray.png', img)
Nós simplesmente passamos as_gray
Como True
para o imread()
método que aprendemos na seção anterior.
o imsave()
O método aceita um nome de arquivo e a matriz de imagens como seu primeiro e segundo parâmetros. Por padrão, o método também verifica se a imagem que você está salvando tem baixo contraste e avisa se for o caso.
Outra maneira de fazer uma imagem em tons de cinza é com a ajuda de rgb2gray()
método do módulo de cores. Simplesmente passamos um array que representa nossa imagem como o primeiro parâmetro. A saída nos dá uma nova matriz que representa a imagem em tons de cinza. Os cálculos finais de luminância são feitos usando os seguintes pesos para diferentes canais.
L = 0.2125*R + 0.7154*G + 0.0721*B
Aqui está o código Python que cria a imagem em tons de cinza:
from skimage import io, color img = io.imread('pizzeria.png') img_grayscale = color.rgb2gray(img) io.imsave('gray-pizzeria.png', img_grayscale)
Para mostrar a nova imagem em tons de cinza, adicione o seguinte ao final do script:
show_grayscale = io.imshow(img_grayscale) io.show()
O resultado fica assim:



Aplicando um filtro a uma imagem
No processamento de imagens, filtragem é executado para fazer alguns aprimoramentos na imagem. Em geral, a filtragem engloba as seguintes operações: aprimoramento de borda, nitidez e suavização.
Nesta seção, mostrarei como podemos aplicar o filtro Sobel em nossa imagem e ver como fica a saída após realizar tal operação.
O script para aplicar o filtro Sobel em nossa imagem tem a seguinte aparência:
from skimage import io, filters img = io.imread('pizzeria.png') sobel_a = filters.sobel(img) io.imsave('sobel-filter.png', sobel_a)
Você provavelmente receberá um aviso ao tentar executar o script acima. Não foi possível aplicar a operação, pois a imagem deve ser uma imagem 2D. Uma solução para este problema é o uso do segundo parâmetro e as_gray
para True
. A saída desta operação é a seguinte:



Existem muitos outros filtros que você pode aplicar, como o filtro gaussiano para desfoque. Ele aceita vários parâmetros sendo o primeiro a imagem fonte e o segundo o desvio padrão para o filtro gaussiano. Você pode passar um único valor ou uma sequência de valores (um para cada eixo). Aqui estão dois exemplos:
from skimage import io, color, filters img = io.imread('pizzeria.png') gaussian_a = filters.gaussian(img, 10) gaussian_b = filters.gaussian(img, [20, 1]) io.imsave('gaussian-filter-10.png', gaussian_a) io.imsave('gaussian-filter-20-1.png', gaussian_b)
Aqui está o resultado da aplicação do filtro Gaussiano com desvio padrão de 10 na imagem da Pizzaria:



Aqui está o resultado da aplicação do filtro gaussiano com desvio padrão de 20 e 1 para os eixos vertical e horizontal:



Agora, vamos ver como podemos aplicar o filtro de limite à nossa imagem. Primeiro, calculamos o valor limite com base na média de todos os valores de escala de cinza em nossa imagem usando o threshold_mean()
método. Depois disso, nós binarizamos nossa imagem e definimos pixels como True
ou False
dependendo se eles estão acima do limite ou não. Essa imagem binária é então convertida em dados uint de 8 bits usando o img_as_ubyte()
método.
from statistics import mean from skimage import io, filters, util img = io.imread('pizzeria.png', as_gray=True) mean_threshold = filters.threshold_mean(img) # Outputs: 0.5637301749456196 print(mean_threshold) binary = img > mean_threshold binary = util.img_as_ubyte(binary) io.imsave('threshold-filter.png', binary)
O código acima produz o seguinte resultado para nossa imagem:



Conclusão
Existem muitas operações de processamento de imagem, e o scikit-image
A biblioteca Python nos fornece muitas operações interessantes que podemos realizar em nossas imagens. Você pode ver mais operações de processamento de imagem usando esta biblioteca no site scikit-image.
Aprenda Python
Aprenda Python com nosso guia tutorial completo sobre Python, seja você apenas começando ou um programador experiente procurando aprender novas habilidades.