Tutorial 2 - Manipulação básica de imagens

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:

  1. Clique no ícone da pastinha no menu lateral esquerdo.

  2. 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>

png

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

png

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

png

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>

png


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>

png


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>

png

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>

png


FAÇA VOCÊ

Realize o espelhamento vertical da imagem.

# SEU CÓDIGO AQUI

Resultado:


<matplotlib.image.AxesImage at 0x7f76480fb0f0>

png


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>

png


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>

png

plt.imshow(cv2.rotate(img_dolar, cv2.ROTATE_180), cmap='gray', vmin=0, vmax=255)
<matplotlib.image.AxesImage at 0x7f7647db3358>

png