lab-x-nome-sobrenome.ipynb
.# IMPLEMENTE O SEU CÓDIGO AQUI
.Ctrl + Enter
para finalizar a edição.Ctrl + Enter
ou clique em Run
no menu do Jupyter.import cv2 # opencv para manipulação de imagens
import numpy as np # numpy para manipulação de matrizes e arrays
import matplotlib.pyplot as plt # pyplot para plotagem de gráficos e imagens
import urllib.request as url # urllib para baixar arquivos via HTTPS
import zipfile # zipfile para lidar com pastas compactadas
# baixando as imagens de referência
url.urlretrieve('https://github.com/Alyssonmach/pdi-labs/raw/main/imagens.zip', 'imagens.zip')
with zipfile.ZipFile('imagens.zip', 'r') as zip_ref:
zip_ref.extractall('')
Podemos utilizar a biblioteca Numpy para escrever arrays e matrizes de forma semelhante ao Matlab:
a) A = np.array( [1, 2, 3, 4, 5])
b) B = np.array( [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ])
c) C = np.array( [ [ [1, 2], [3, 4] ], [ [1, 2], [3, 4] ] ])
Descrição:
A = np.array([1, 2, 3, 4, 5])
B = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
C = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print("Array A: {}".format(A))
print("Shape de A: {}".format(A.shape))
print("Array B:\n{}".format(B))
print("Shape de B: {}".format(B.shape))
print("Array C:\n{}".format(C))
print("Shape de C: {}".format(C.shape))
Elementos internos dos arrays podem ser acessados utilizando colchetes, por exemplo:
print("A[0] == {}".format(A[0]))
print("B[0,2] == {}".format(B[0,2]))
print("C[1, 0, 1] == {}".format(C[1, 0, 1]))
Também é possível acessar fatias do array utilizando o operador :
como pode ser visto a seguir:
print("A[0:4]: {}\n".format(A[0:4]))
print("B[2, 0:2]: {}\n".format(B[2, 0:2]))
print("C[0, :, :]:\n{}".format(C[0, :, :]))
A1 = A[1:4]
B1 = B[1:2, 0:1]
B2 = B[-1, -2]
C1 = C[-2, -2, -2]
C2 = C[0, 0, 0]
C3 = C[:, 0, 0]
# IMPLEMENTE SEU CÓDIGO AQUI -> QUESTÃO 1 - LETRA (a)
Vamos trabalhar com quatro tipos de imagens:
a. Imagens de Intensidades: São matrizes cujos valores representam intensidades em cada ponto. Elementos de intensidade da classe uint8 terão valores no intervalo [0, 255]. Já elementos da classe uint16 terão valores entre [0, 65535].
b. Imagens Binárias: São um arranjo lógico em forma de matriz cujos valores são booleanos, podendo ser 0s ou 1s;
c. Imagens Indexadas: São imagens cujo valor de cada pixel está associado a uma cor descrita por um mapa de cores (colormap);
d. Imagens Coloridas: São Imagens com múltiplos canais onde os múltiplos valores associados a um determinado pixel descrevem a sua cor. Um exemplo seriam imagens RGB, onde os diferentes canais descrevem a intensidade luminosa das cores vermelho (R), verde (G) e azul (B), respectivamente, de uma imagem;
# a próxima linha de código torna a figura do matplotlib interativa, permitindo visualizar os valores de cada pixel
# a figura deixará de ser interativa quando outra célula for executada
# é possível reativá-la ao rodar essa célula novamente
%matplotlib notebook
# um array do numpy pode ser interpretado como uma imagem de intensidade
I = np.array([[0, 50, 100, 150, 200, 250],
[0, 50, 100, 150, 200, 250],
[0, 50, 100, 150, 200, 250],
[0, 50, 100, 150, 200, 250],
[0, 50, 100, 150, 200, 250]]).astype(np.uint8)
# podemos utilizar o matplotlib para visualizar a imagem através da função imshow
plt.figure(figsize = (4, 4))
plt.imshow(I, cmap = "gray")
%matplotlib notebook
fig, axs = plt.subplots(nrows = 2, ncols = 3, figsize=(8, 6))
# primeira linha de subfiguras
# primeira subfigura
axs[0][0].imshow(I)
axs[0][0].set_title("Colormap Padrão", fontsize = 10)
# segunda subfigura
axs[0][1].imshow(I, cmap = "gray")
axs[0][1].set_title("Colormap em Escala de Cinza", fontsize = 10)
# terceira subfigura
axs[0][2].imshow(I, cmap = "Purples")
axs[0][2].set_title("Colormap em tons de roxo", fontsize = 10)
# segunda linha de subfiguras
# primeira subfigura
axs[1][0].imshow(I, cmap="Reds")
axs[1][0].set_title("Colormap em tons de vermelho", fontsize = 10)
# segunda subfigura
axs[1][1].imshow(I, cmap="Greens")
axs[1][1].set_title("Colormap em tons de verde", fontsize = 10)
# terceira subfigura
axs[1][2].imshow(I, cmap="Blues")
axs[1][2].set_title("Colormap em tons de azul", fontsize = 10)
# Referências de colormaps: https://matplotlib.org/stable/tutorials/colors/colormaps.html
%matplotlib notebook
fig, axs = plt.subplots(nrows = 2, ncols = 3, figsize=(8, 6))
# primeira linha de subfiguras
# primeira Subfigura
axs[0][0].imshow(I, cmap = "gray")
axs[0][0].set_title("Valores Padrão", fontsize = 10)
# segunda Subfigura
axs[0][1].imshow(I, vmin = 100, vmax = 200, cmap = "gray")
axs[0][1].set_title("vmin = 100, vmax = 200", fontsize = 10)
# terceira Subfigura
axs[0][2].imshow(I, vmin = 25, vmax = 75, cmap = "gray")
axs[0][2].set_title("vmin = 25, vmax = 75", fontsize = 10)
## segunda linha de subfiguras
# primeira Subfigura
axs[1][0].imshow(I, vmin = -1, vmax = 0, cmap = "gray")
axs[1][0].set_title("vmin = -1, vmax = 0", fontsize = 10)
# segunda Subfigura
axs[1][1].imshow(I, vmin = 115, vmax = 125, cmap = "gray")
axs[1][1].set_title("vmin = 115, vmax = 125", fontsize = 10)
# terceira Subfigura
axs[1][2].imshow(I, vmin = 255, vmax = 256, cmap = "gray")
axs[1][2].set_title("vmin = 255, vmax = 256", fontsize = 10)
%matplotlib notebook
fig, axs = plt.subplots(nrows = 1, ncols = 3, figsize=(8, 6))
# é preciso se atentar aos valores da matriz ao converter entre os tipos de array
I16 = np.array([[ 0, 0, 0, 0, 0, 0],
[ 50, 50, 50, 50, 50, 50],
[100, 100, 100, 100, 100, 100],
[150, 150, 150, 150, 150, 150],
[200, 200, 200, 200, 200, 200],
[250, 250, 250, 250, 250, 250],
[300, 300, 300, 300, 300, 300]]).astype(np.uint16)
axs[0].imshow(I16, vmin = 0, vmax = 255, cmap = "gray")
axs[0].set_title("Imagem Original uint16", fontsize = 10)
axs[0].set_xlabel("vmin = 0\n vmax = 255", fontsize = 10)
# a conversão direta sem o reescalonamento dos valores pode produzir resultados inesperados
I8a = I16.astype(np.uint8)
axs[1].imshow(I8a, vmin = 0, vmax = 255, cmap = "gray")
axs[1].set_title("Imagem uint8 s/ \nreescalonamento", fontsize = 10)
axs[1].set_xlabel("vmin = 0\n vmax = 255", fontsize = 10)
# o reescalonamento melhora os resultados, mas como uint8 não aceita valores decimais, ocorrem erros de quantização
rescale_factor = 255 / np.max(I16)
I8b = ( rescale_factor * I16 ).astype(np.uint8)
axs[2].imshow(I8b, vmin = 0, vmax = 255, cmap = "gray")
axs[2].set_title("Imagem uint8 c/ \nreescalonamento", fontsize = 10)
axs[2].set_xlabel("vmin = 0\n vmax = 255", fontsize = 10)
%matplotlib notebook
fig, axs = plt.subplots(nrows = 1, ncols = 3, figsize=(8, 6))
# é preciso se atentar aos valores da matriz ao converter entre os tipos de array
I8 = np.array([[36, 47, 75, 32, 18],
[0, 90, 0, 67, 29],
[150, 22, 50, 20, 54],
[50, 34, 65, 40, 50],
[6, 50, 5, 50, 13],
[39, 1, 50, 25, 0]]).astype(np.uint8)
axs[0].imshow(I8, vmin = 0, vmax = 255, cmap = "gray")
axs[0].set_title("Imagem Original uint8", fontsize = 10)
axs[0].set_xlabel("vmin = 0\n vmax = 255", fontsize = 10)
# imagens formadas a partir de arrays float32 são tipicamente utilizadas em aplicações de IA como redes convolucionais
# nesse caso, a conversão pode ser realizada dividindo os elementos da matriz por 255, maior valor para imagens uint8
# como o tipo float32 aceita valores decimais e dispõe de mais bits para representar os valores, não ocorrem perdas.
Ifloat = (I8 / 255).astype(np.float32)
axs[1].imshow(Ifloat, vmin=0, vmax=1, cmap = "gray")
axs[1].set_title("Imagem Float", fontsize = 10)
axs[1].set_xlabel("vmin = 0\n vmax = 1.0", fontsize = 10)
# imagens (ou máscaras) binárias são geralmente utilizadas para a extração de características em imagens
# nesse caso, a conversão pode ser realizada a partir de um processo de limiarização (thresholding)
# os valores booleanos podem ser convertidos em números (0s e 1s) mudando o tipo de array para float ou uint
Ibin = (I8 >= 50)
axs[2].imshow(Ibin, cmap = "gray")
axs[2].set_title("Imagem Binária", fontsize = 10)
axs[2].set_xlabel("vmin = False\n vmax = True", fontsize = 10)
A = [[16, 3, 2, 13], [6, 9, 12, 7], [5, 10, 11, 8], [4, 15, 14, 8]]
B = [[16, 8, 2, 4], [20, 30, 40, 50], [5, 7, 8, 11]]
C = [[20, 30, 40], [50, 90, 15], [80, 30, 10]]
D = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 8, 8, 9], [8, 7, 7, 8], [4, 5, 9, 8]]
IA = A
IB = B, vmin = 4, vmax = 30
IC = C, vmin = 15, vmax = 20
ID = D, vmin = 0, vmax = 20
# IMPLEMENTE SEU CÓDIGO AQUI -> QUESTÃO 3 - LETRA (a)
# IMPLEMENTE SEU CÓDIGO AQUI -> QUESTÃO 3 - LETRA (b)
G = [[-0.7, 1.2, 0.4, -0.6, -0.4, 1.2], [-1.6, -0.6, 0.4, 0.8, 0.0, 0.8], [1.5, -0.5, 0.1, 0.2, -0.8, 1.1], [2.1, 0.9, 0.5, -0.5, -1.6, -0.7], [0.1, -1.4, 1.1, -1.2, 0.2, -0.9], [-1.0, -2.0, 1.0, 0.6, -0.1, -1.3]]
# IMPLEMENTE SEU CÓDIGO AQUI - QUESTÃO 4
%matplotlib notebook
G = np.array([[-0.7, 1.2, 0.4, -0.6, -0.4, 1.2], [-1.6, -0.6, 0.4, 0.8, 0.0, 0.8],
[1.5, -0.5, 0.1, 0.2, -0.8, 1.1], [2.1, 0.9, 0.5, -0.5, -1.6, -0.7],
[0.1, -1.4, 1.1, -1.2, 0.2, -0.9], [-1.0, -2.0, 1.0, 0.6, -0.1, -1.3] ]).astype(np.float32)
# produzindo G1 a partir de G
G1 = G - np.min(G)
rescale_factor = 255 / np.max(G1)
G1 = (rescale_factor * G1).astype(np.uint8)
G1 = (G1 / 255).astype(np.float32)
# produzindo G2 a partir de G
G2 = G - np.min(G)
G2 = (G2 / np.max(G2)).astype(np.float32)
fig, axs = plt.subplots(nrows = 1, ncols = 2, figsize=(8, 6))
axs[0].imshow(G1, vmin=0, vmax=1, cmap="gray")
axs[0].set_title("Imagem G1", fontsize=10)
axs[1].imshow(G2, vmin=0, vmax=1, cmap="gray")
axs[1].set_title("Imagem G2", fontsize=10)
print('Informações Estatísticas de G:\n')
print('Dimensão da Imagem:', G.shape)
print('Quantidade de Pixels:', G.size)
print('Média: {:.3f}'.format(np.mean(G)))
print('Desvio Padrão: {:.3f}'.format(np.std(G)))
print('Valor Mínimo:', np.min(G))
print('Valor Máximo:', np.max(G))
print('\nInformações Estatísticas de G1:\n')
print('Dimensão da Imagem:', G1.shape)
print('Quantidade de Pixels:', G1.size)
print('Média: {:.3f}'.format(np.mean(G1)))
print('Desvio Padrão: {:.3f}'.format(np.std(G1)))
print('Valor Mínimo:', np.min(G1))
print('Valor Máximo:', np.max(G1))
print('\nInformações Estatísticas de G2:\n')
print('Dimensão da Imagem:', G2.shape)
print('Quantidade de Pixels:', G2.size)
print('Média: {:.3f}'.format(np.mean(G2)))
print('Desvio Padrão: {:.3f}'.format(np.std(G2)))
print('Valor Mínimo:', np.min(G2))
print('Valor Máximo:', np.max(G2))
A biblioteca OpenCV possibilita carregar imagens do computador como arrays do numpy através da função imread (Observe que o comando cv2.imread lê uma imagem colorida como BGR, enquanto o comando plt.imread lê como RGB):
Sintaxe: im = cv2.imread( filepath, 0)
Descrição: A função carrega a o arquivo cujo caminho está contido na string
# IMPLEMENTE O SEU CÓDIGO AQUI -> QUESTÃO 6 - LETRA (a)
# IMPLEMENTE O SEU CÓDIGO AQUI -> QUESTÃO 6 - LETRA (b)
A biblioteca OpenCV possibilita redimensionar imagens carregadas através da função resize:
Sintaxe: dst_img = cv2.resize(src_img, (cols, rows))
Descrição: A função altera as dimensões da imagem <src_img> para as dimensões fornecidas (cols, rows), retornando <dst_img>, que é a imagem redimensionada. <src_img> pode ser uma imagem monocromática, colorida ou binária e as novas dimensões podem ser maiores ou menores que as originais.
(a) Carregue a imagem mandril.tiff e altere suas dimensões utilizando a função resize para as dimensões listadas a seguir. Verifique as dimensões de cada imagem para confirmar o redimensionamento.
(b) Plote as imagens redimensionadas utilizando subplots e comente os resultados observados.
(c) Comente os resultados obtidos.
# IMPLEMENTE O SEU CÓDIGO AQUI -> QUESTÃO 7 - LETRA (a)
# IMPLEMENTE O SEU CÓDIGO AQUI - QUESTÃO 7 - LETRA (b)