Neste tutorial vamos aprender algumas operações básicas de manipulação de imagens utilizando a biblioteca OpenCV.
As imagens utilizadas estão disponíveis como recursos educacionais na página: http://www.imageprocessingplace.com/DIP-3E/dip3e_book_images_downloads.htm
Bibliotecas e pacotes
import cv2
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
Carregando uma imagem
Para carregar e manipular uma imagem, primeiro é preciso fazer o upload um arquivo de imagem no ambiente virtual do Google Colab:
Clique no ícone da pastinha no menu lateral esquerdo.
Utilize o ícone de upload ou arraste o arquivo desejado para a área do menu lateral.
Após o upload, o arquivo estará disponível no diretório base do ambiente.
FAÇA VOCÊ
Baixe essa imagem e faça o upload no ambiente.
A função imread() do openCV é utilizada para carregar uma imagem de um arquivo. Basta passar como argumentos o caminho do arquivo e o modo de abertura (escala de cinza ou colorido).
img_dolar = cv2.imread("Fig0115(b)(100-dollars).tif", cv2.IMREAD_GRAYSCALE)
Propriedades da imagem
img_dolar
array([[194, 194, 194, ..., 194, 194, 194],
[194, 194, 194, ..., 194, 194, 194],
[194, 194, 194, ..., 194, 194, 194],
...,
[194, 194, 194, ..., 194, 194, 194],
[194, 194, 194, ..., 194, 194, 194],
[194, 194, 194, ..., 194, 194, 194]], dtype=uint8)
Observe acima que a imagem carregada nada mais é do que um array bidimensional. Cada pixel é caracterizado por uma coordenada (x,y) e um valor de intensidade. O tamanho dessa matriz/imagem é determinada pelo número de colunas/largura (m) e linhas/altura (n) da matriz (m x n).
img_dolar.shape
(500, 1192)
A imagem possui 500 px de altura e 1192 px de largura
img_dolar.max()
247
O valor máximo de intensidade da imagem é 247.
FAÇA VOCÊ
Descubra o valor mínimo e médio da intensidade dos pixels da imagem.
# SEU CÓDIGO AQUI
Resultado:
Mínimo: 0
Médio: 152.58884228187918
Visualizando uma imagem
Para visualizar a representação da imagem de fato, e não a matriz, precisamos utilizar a função plt.imshow().
Passamos como argumentos a imagem carregada, o mapa de cores utilizado e os valores mínimos e máximos que os pixels podem assumir.
plt.imshow(img_dolar, cmap='gray', vmin=0, vmax=255)
<matplotlib.image.AxesImage at 0x7f36775184e0>
Perceba a necessidade de informar os valores dos parâmetros vmin e vmax. Os valores mínimos e máximos esperados para uma imagem de 8 bits em escala de cinza são 0 e 255, respectivamente.
Cuidado: se vmin e vmax não forem definidos, o matplotlib irá definir com base nos valores existentes na imagem e isso pode acabar ajustanto o contraste automaticamente.
O uso de subplots pode ajudar mais tarde quando precisaremos fazer comparações entre imagens após algumas operações. Consulte a documentação para melhor compreensão dos arranjos possíveis.
plt.subplot(2,1,1) # 2 linhas, 1 coluna, posição 1
plt.title('Uma imagem')
plt.imshow(img_dolar, cmap='gray', vmin=0, vmax=255)
plt.subplot(2,1,2) # 2 linhas, 1 coluna, posição 2
plt.title('A mesma imagem')
plt.imshow(img_dolar, cmap='gray', vmin=0, vmax=255)
plt.tight_layout() # evita a sobreposição dos eixos das imagens
plt.subplot(1,2,1) # 1 linha, 2 colunas, posição 1
plt.title('Uma imagem')
plt.imshow(img_dolar, cmap='gray', vmin=0, vmax=255)
plt.subplot(1,2,2) # 1 linha, 2 colunas, posição 2
plt.title('A mesma imagem')
plt.imshow(img_dolar, cmap='gray', vmin=0, vmax=255)
plt.tight_layout() # evita a sobreposição dos eixos das imagens
Operações básicas com imagens
Corte seletivo
Como vimos anteriormente, as imagens são representadas por arrays bidimensionais. Nesse caso, podemos utilizar as propriedades de slicing de arrays em Python!
Fazer um slice significa selecionar os elementos de um índice até outro do array: meu_array[inicio:fim].
Como estamos lidando com arrays bidimensionais, as posições de inicio e fim devem ser definidas tanto para as linhas quanto para as colunas: meu_array[inicio:fim, inicio:fim]
corte = img_dolar[400:500, 0:300]
plt.imshow(corte, cmap='gray', vmin=0, vmax=255)
<matplotlib.image.AxesImage at 0x7feed0873240>
FAÇA VOCÊ
Realize o slicing da região que contém o texto “ONE HUNDRED DOLLARS” no canto inferior direito da imagem.
Dica: esse é um processo apenas aproximado e manual. Observe os eixos x e y da imagem original plotada e tente encontrar os valores aproximados das coordenadas para a região.
#SEU CÓDIGO AQUI
O resultado final deve ser parecido com a imagem abaixo:
<matplotlib.image.AxesImage at 0x7feed07af400>
Espelhamento
Para espelhar imagens também podemos aproveitar as propriedades de um array ao utilizar um passo negativo (-1) para inverter a direção desejada:
meu_array[inicio:fim, inicio:fim:-1], irá espelhar a imagem horizontalmente
img_dolar_flip_horizontal = img_dolar_flip_horizontal[::,::-1]
plt.imshow(img_dolar_flip_horizontal, cmap='gray', vmin=0, vmax=255)
<matplotlib.image.AxesImage at 0x7f764811c668>
Outro modo é com a utilização da função flip() do openCV:
img_dolar_flip_horizontal = cv2.flip(img_dolar, flipCode=1)
plt.imshow(img_dolar_flip_horizontal, cmap='gray', vmin=0, vmax=255)
<matplotlib.image.AxesImage at 0x7f7651d7f358>
FAÇA VOCÊ
Realize o espelhamento vertical da imagem.
# SEU CÓDIGO AQUI
Resultado:
<matplotlib.image.AxesImage at 0x7f76480fb0f0>
Rotação
O pacote openCV oferece a função rotate() para rotacionar as imagens.
Veja abaixo como rotacionar em 90º no sentido horário:
img_dolar_90_cw = cv2.rotate(img_dolar, cv2.ROTATE_90_CLOCKWISE)
plt.imshow(img_dolar_90_cw, cmap='gray', vmin=0, vmax=255)
<matplotlib.image.AxesImage at 0x7f7647e7e8d0>
FAÇA VOCÊ
Realize as rotações de 90º no sentido anti-horário e 180º da imagem.
# SEU CÓDIGO AQUI
Resultado
plt.imshow(cv2.rotate(img_dolar, cv2.ROTATE_90_COUNTERCLOCKWISE), cmap='gray', vmin=0, vmax=255)
<matplotlib.image.AxesImage at 0x7f7647ddb588>
plt.imshow(cv2.rotate(img_dolar, cv2.ROTATE_180), cmap='gray', vmin=0, vmax=255)
<matplotlib.image.AxesImage at 0x7f7647db3358>