Caso 2D: https://objetos.github.io/docs/demos/image_conv_vis/¶
Kernel: matriz de pesos $(w_{mn})$.
$g(x,y) = w(x,y)*f(x,y) = \sum_{s=-a}^{a}\sum_{t=-b}^{b} w(s,t)f(x-s,y-t)$
- Coloque o centro do kernel sobre o pixel que você está analisando.
- Multiplique cada elemento do kernel pelo valor do pixel correspondente na imagem (a região coberta).
- Some todos esses produtos para obter um único número, que se torna o novo valor desse pixel na saída.

Assim, a convolução é simplesmente "deslizar um pequeno molde de números sobre a imagem e calcular uma soma ponderada" em cada posição, produzindo efeitos variados dependendo do padrão escolhido para o kernel.
Propriedades da Convolução¶
Comutatividade
Associatividade
Distributividade
Associatividade com multiplicação escalar
Imports e Preparação¶
import cv2
import numpy as np
import matplotlib.pyplot as plt
from urllib.request import urlopen
SEED = 1234
np.random.seed(SEED)
Playground: Testando filtros imagem binária¶
# Cria imagem aletória
img_size = 16
rnd_img = np.random.randint(0, 2, size=(img_size,img_size),dtype=np.uint8)
kernel = np.array( # Define um kernel
[[0, 0, 0],
[0, 0, 1],
[0, 0, 0]],
np.float32)
resultado_img = cv2.filter2D(rnd_img, -1, kernel) # Convolução
show_images_playground(rnd_img, resultado_img, img_size)
Carregamento de Imagem¶
img = url_to_image("https://www.flickr.com/photo_download.gne?id=16504233985&secret=9f1060624e&size=q&source=photoPageEngagement")
plt.figure(figsize=(3,3))
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.show()
Filtro de Média¶
Utilizado para suavização da imagem.
Diminui a nitidez pela redução de fortes transições de intensidade entre os pixels.

Filtro de Média: Aplicação¶
# Define um kernel de suavização (média)
kernel = np.ones((3,3), np.float32) / 9
# Aplica a convolução com o kernel
media_img = cv2.filter2D(img, -1, kernel)
# Mostra as imagens original e suavizada
show_images(img, media_img)
Filtro de Média: Kernels de diferentes tamanhos¶
# Cria a estrutura de plots para as imagens
figure, axarr = plt.subplots(1,5, figsize=(10,10))
axarr[0].imshow(img, cmap= 'gray')
axarr[0].set_title("Imagem Original")
for cnt, size in enumerate([3, 5, 9, 15]):
# Define um kernel de suavização (média)
kernel = np.ones((size,size), np.float32) / (size**2)
# Aplica a convolução com o kernel
imagem_suavizada = cv2.filter2D(img, -1, kernel)
# Mostra as imagens original e suavizada
axarr[cnt+1].imshow(imagem_suavizada, cmap= 'gray')
axarr[cnt+1].set_title(f"Kernel ({size} x {size})")
# Remove plt grid e ticks
for ax in axarr.ravel():
ax.set_axis_off()
plt.tight_layout()
plt.show()
Filtro de Média: Diferentes valores de Kernel¶
kernel_media = np.array([
[1, 2, 1],
[2, 4, 2],
[1, 2, 1],
]).astype(np.float16)
kernel_media /= kernel_media.sum()
imagem_suavizada = cv2.filter2D(img, -1, kernel_media)
figure, axarr = plt.subplots(1,2, figsize=(6,6))
axarr[0].imshow(img, cmap= 'gray')
axarr[1].imshow(imagem_suavizada, cmap= 'gray')
for ax in axarr.ravel():
ax.set_axis_off()
plt.show()
Filtro Gaussiano¶
Suavização: Filtro de média ponderada, mas com seus pesos seguindo uma aproximação da distribuição gaussiana.
$G(x,y;\sigma)=\frac{1}{2\pi\sigma^{2}}\exp\!\left(-\,\frac{x^{2}+y^{2}}{2\sigma^{2}}\right)$
Note que o valor resultante para o elemento central pode ser um valor não existente na imagem original.
Fonte da Imagem: Towards AI.
Filtro Gaussiano: Aplicação¶
# Suavização Gaussiana (Filtro Gaussiano)
kernel_size = (5, 5)
sigma = 1.0
# Aplica o filtro Gaussiano
blurred = cv2.GaussianBlur(img, kernel_size, sigmaX=sigma)
figure, axarr = plt.subplots(1,2, figsize=(6,6))
axarr[0].imshow(img, cmap= 'gray')
axarr[1].imshow(blurred, cmap= 'gray')
# Remove plt grid e ticks
for ax in axarr.ravel():
ax.set_axis_off()
plt.show()
Filtro Gaussiano: Testando diferentes valores de $\sigma$¶
# Cria a estrutura de plots para as imagens
figure, axarr = plt.subplots(1,5, figsize=(10,5))
axarr[0].imshow(img, cmap= 'gray')
axarr[0].set_title("Imagem Original")
for cnt, sigma in enumerate([0.5, 1, 1.5, 2]):
# Aplica o filtro Gaussiano
gauss_img = cv2.GaussianBlur(img, kernel_size, sigmaX=sigma)
# Mostra as imagens original e suavizada
axarr[cnt+1].imshow(gauss_img, cmap= 'gray')
axarr[cnt+1].set_title(f"Sigma: {sigma}")
ax.set_axis_off()
# Remove plt grid e ticks
for ax in axarr.ravel():
ax.set_axis_off()
plt.tight_layout()
plt.show()
Comparação: Filtro de Média versus Filtro Gaussiano¶
kernel_size = (5, 5)
avg_img = cv2.blur(img, kernel_size)
gaussian_img = cv2.GaussianBlur(img, kernel_size, sigmaX=1.0)
figure, axarr = plt.subplots(1,3, figsize=(8,8))
axarr[0].imshow(img, cmap= 'gray')
axarr[0].set_title("Imagem Original")
axarr[1].imshow(avg_img, cmap= 'gray')
axarr[1].set_title(f"Filtro Média {str(kernel_size).replace(',', ' x ')}")
axarr[2].imshow(gaussian_img, cmap= 'gray')
axarr[2].set_title(f"Filtro de Gaussiano {str(kernel_size).replace(',', ' x ')}")
for ax in axarr.ravel():
ax.set_axis_off()
plt.show()
Filtro Mediana¶
- Elimina picos isolados (outliers).
- Substitui o valor de um pixel pela mediana dos valores de intensidade na vizinhança desse pixel.

Fonte da Imagem: ResearchGate.
Filtro Mediana: Aplicação¶
# Aplica filtro de mediana
median_filtered = cv2.medianBlur(img, ksize=3)
figure, axarr = plt.subplots(1,2, figsize=(8,8))
axarr[0].imshow(img, cmap= 'gray')
axarr[0].set_title("Imagem Original")
axarr[1].imshow(median_filtered, cmap= 'gray')
axarr[1].set_title("Imagem Filtrada pela Mediana")
for ax in axarr.ravel():
ax.set_axis_off()
plt.show()
Filtro de Mediana: Removendo Ruído Salt-and-Pepper¶
def add_salt_and_pepper_noise(image, noise_ratio=0.02):
noisy_image = image.copy()
h, w = noisy_image.shape
noisy_pixels = int(h * w * noise_ratio)
for _ in range(noisy_pixels):
row, col = np.random.randint(0, h), np.random.randint(0, w)
if np.random.rand() < 0.5:
noisy_image[row, col] = 0
else:
noisy_image[row, col] = 255
return noisy_image
ruido_img = add_salt_and_pepper_noise(img)
mediana_filtrada_img = cv2.medianBlur(ruido_img, ksize=3)
figure, axarr = plt.subplots(1,3, figsize=(11,8))
axarr[0].imshow(img, cmap= 'gray')
axarr[0].set_title("Imagem Original")
axarr[1].imshow(ruido_img, cmap= 'gray')
axarr[1].set_title("Imagem Ruidosa (Salt and Pepper)")
axarr[2].imshow(mediana_filtrada_img, cmap= 'gray')
axarr[2].set_title("Imagem Filtrada pela Mediana")
# Remove plt grid e ticks
for ax in axarr.ravel():
ax.set_axis_off()
plt.show()
Filtro Sobel¶
- O filtro de Sobel é um operador discreto de derivação, projetado para estimar a magnitude do gradiente de intensidade em imagens digitais. $\rightarrow$ Combina duas convoluções separadas: uma kernel $h_x$ que responde à variação horizontal e outra $h_y$ que captura a variação vertical.
- A combinação das respostas $\sqrt{(I * h_x)^2 + (I * h_y)^2}$ fornece uma aproximação robusta da magnitude do gradiente, enquanto o sinal de cada componente indica a direção local do aumento ou diminuição de intensidade.
- Eficaz na detecção de bordas: Enfatiza regiões com transições rápidas de luminância. Suaviza ruídos graças à integração de ponderações gaussiana-like nos kernels.
Filtro Sobel: Exemplo¶
Filtro Sobel: Aplicação¶
sobel_img = cv2.Sobel(img, ddepth=-1, dx=1, dy=0, ksize=3)
figure, axarr = plt.subplots(1,2, figsize=(8,8))
axarr[0].imshow(img, cmap= 'gray')
axarr[0].set_title("Imagem Original")
axarr[1].imshow(sobel_img, cmap= 'gray')
axarr[1].set_title("Filtro Sobel")
for ax in axarr.ravel():
ax.set_axis_off()
plt.show()
Filtro Laplaciano¶
- O operador laplaciano é uma segunda derivada discreta que mede a divergência do gradiente de intensidade de uma imagem.
- $Laplace(f) = \dfrac{\partial^{2} f}{\partial x^{2}} + \dfrac{\partial^{2} f}{\partial y^{2}}$
- Captura a divergência do gradiente de intensidade de uma imagem, ou seja, quantifica as regiões onde a curvatura da luminância muda drasticamente.
- Soma ponderada dos vizinhos diretos do pixel central, subtraindo quatro vezes seu valor.
- Destaca pontos de mudança abrupta — bordas e cantos — mas não indica a direção dessas transições.
- Kernels laplacianos geralmente incluem valores negativos na vizinhança e um valor igual à soma destes valores negativos no centro, mas
com sinal invertido: $$K = \begin{bmatrix}0 & -1 & 0\\ -1 & 4 & -1\\ 0 & -1 & 0\end{bmatrix}$$
Filtro Laplaciano: Aplicação¶
laplacean_img = cv2.Laplacian(img, ddepth=-1, ksize=3)
figure, axarr = plt.subplots(1,2, figsize=(8,8))
axarr[0].imshow(img, cmap= 'gray')
axarr[0].set_title("Imagem Original")
axarr[1].imshow(laplacean_img, cmap= 'gray')
axarr[1].set_title("Filtro Laplaciano")
for ax in axarr.ravel():
ax.set_axis_off()
plt.show()
Outros Filtros¶
Prewitt
- Operador linear de 3×3 usado para detecção de bordas.
- Calcula aproximações das derivadas parciais ∂I/∂x e ∂I/∂y.
$$ G_x=\begin{bmatrix}-1&0&1\\-1&0&1\\-1&0&1\end{bmatrix},\quad G_y=\begin{bmatrix}-1&-1&-1\\0&0&0\\1&1&1\end{bmatrix} $$ - Resultado: imagem com bordas destacadas; suaviza ruído moderado, porém menos sensível que Sobel.
Outros Filtros (cont.)¶
Max (Filtro de Maxima)
- Operador não linear que substitui cada pixel pelo maior valor dentro do vizinho definido.
- Reduz ruído impulsivo “salt & pepper”, preservando detalhes mais claros.
- Resultado: imagem com regiões saturadas ampliadas; pode gerar bordas suavizadas em áreas escuras.
Min (Filtro de Minima)
- Operador não linear que substitui cada pixel pelo menor valor dentro do vizinho.
- Útil para eliminar ruído impulsivo salt and pepper nas áreas claras.
- Resultado: diminuição de brilho local, bordas mais suaves em regiões escuras.
Resumo¶
|
![]() Leitura Recomendada: Seções 3.4 a 3.7. |