NumPy: Projeto — Processamento de Imagens

Última atualização: 2026-08-26

1. Projeto: Processamento de Imagens com NumPy

(1) Cenário

Você está trabalhando em um pipeline de visão computacional. Você precisa manipular imagens em nível de pixel — converter para tons de cinza, aplicar filtros e computar estatísticas — tudo usando operações de arrays NumPy.

(2) Tarefas

1. Criar uma Imagem Sintética

PYTHON
import numpy as np

# Criar uma imagem RGB 100x100
rng = np.random.default_rng(42)
image = rng.integers(0, 256, size=(100, 100, 3), dtype=np.uint8)
print(f"Shape da imagem: {image.shape}")  # (100, 100, 3)
print(f"Dtype da imagem: {image.dtype}")  # uint8

2. Converter para Tons de Cinza

PYTHON
# Tons de cinza: média ponderada dos canais RGB
# Pesos padrão: 0.299 R + 0.587 G + 0.114 B
gray = np.dot(image[..., :3], [0.299, 0.587, 0.114]).astype(np.uint8)
print(f"Shape cinza: {gray.shape}")  # (100, 100)

3. Aplicar um Filtro Simples (Detecção de Bordas Horizontais)

PYTHON
# Detecção de bordas: subtrair linhas adjacentes
edges = np.abs(gray[:-1] - gray[1:])
print(f"Shape do mapa de bordas: {edges.shape}")  # (99, 100)
print(f"Intensidade das bordas: média={edges.mean():.1f}, máx={edges.max()}")

4. Extrair Canais de Cor

PYTHON
# Extrair canais individuais
red = image[:, :, 0]
green = image[:, :, 1]
blue = image[:, :, 2]

print(f"Canal vermelho: média={red.mean():.1f}, mín={red.min()}, máx={red.max()}")
print(f"Canal verde: média={green.mean():.1f}, mín={green.min()}, máx={green.max()}")
print(f"Canal azul: média={blue.mean():.1f}, mín={blue.min()}, máx={blue.max()}")

5. Estatísticas da Imagem

PYTHON
# Histograma (simplificado: contar pixels em cada faixa de intensidade)
bins = np.array([0, 50, 100, 150, 200, 256])
indices = np.digitize(gray.ravel(), bins)
hist = np.bincount(indices, minlength=len(bins)+1)[1:-1]

for i in range(len(bins)-1):
    print(f"Intensidade {bins[i]:3d}-{bins[i+1]:3d}: {hist[i]:4d} pixels")

▶ Exemplo: Criando uma imagem sintética (Dificuldade ⭐)

PYTHON
import numpy as np

# Criar uma imagem RGB 50x50 com gradiente
x = np.arange(50)
y = np.arange(50)
xx, yy = np.meshgrid(x, y)

red = np.zeros((50, 50), dtype=np.uint8)
green = (xx * 5).astype(np.uint8)
blue = (yy * 5).astype(np.uint8)

image = np.stack([red, green, blue], axis=-1)
print("Shape:", image.shape)
print("Canal vermelho:", image[:, :, 0].min(), "-", image[:, :, 0].max())
print("Canal verde:", image[:, :, 1].min(), "-", image[:, :, 1].max())
print("Canal azul:", image[:, :, 2].min(), "-", image[:, :, 2].max())

Output:

TEXT 📖 Somente leitura
Shape: (50, 50, 3)
Canal vermelho: 0 - 0
Canal verde: 0 - 245
Canal azul: 0 - 245

▶ Exemplo: Conversão para tons de cinza (Dificuldade ⭐)

PYTHON
import numpy as np

# Simular uma imagem RGB
rng = np.random.default_rng(42)
image = rng.integers(0, 256, size=(10, 10, 3), dtype=np.uint8)

# Pesos padrão para tons de cinza
gray = (0.299 * image[:, :, 0] + 0.587 * image[:, :, 1] + 0.114 * image[:, :, 2]).astype(np.uint8)
print("Shape original:", image.shape)
print("Shape cinza:", gray.shape)
print("Pixel cinza [0, 0]:", gray[0, 0])
print("Média cinza:", gray.mean())

Output:

TEXT 📖 Somente leitura
Shape original: (10, 10, 3)
Shape cinza: (10, 10)
Pixel cinza [0, 0]: 72
Média cinza: 129.0

▶ Exemplo: Detecção de bordas simples (Dificuldade ⭐⭐)

PYTHON
import numpy as np

# Criar uma imagem simples com uma borda vertical
image = np.zeros((10, 10), dtype=np.uint8)
image[:, 5:] = 255

# Detecção de bordas horizontais
h_edges = np.abs(image[:-1, :] - image[1:, :])
print("Bordas horizontais:\n", h_edges)

# Detecção de bordas verticais
v_edges = np.abs(image[:, :-1] - image[:, 1:])
print("Bordas verticais:\n", v_edges)

Output:

TEXT 📖 Somente leitura
Bordas horizontais:
 [[0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]
Bordas verticais:
 [[  0   0   0   0 255   0   0   0   0]
 [  0   0   0   0 255   0   0   0   0]
 [  0   0   0   0 255   0   0   0   0]
 [  0   0   0   0 255   0   0   0   0]
 [  0   0   0   0 255   0   0   0   0]
 [  0   0   0   0 255   0   0   0   0]
 [  0   0   0   0 255   0   0   0   0]
 [  0   0   0   0 255   0   0   0   0]
 [  0   0   0   0 255   0   0   0   0]]


❓ Perguntas Frequentes

P: Por que usar 0.299 R + 0.587 G + 0.114 B para tons de cinza? R: Esses pesos correspondem à percepção humana — somos mais sensíveis ao verde, menos ao azul. A média simples (R+G+B)/3 ignora isso e produz resultados desbotados.

P: Posso processar imagens reais com NumPy? R: Sim — carregue imagens com matplotlib.pyplot.imread() ou imageio.imread(), que retornam arrays NumPy. Depois aplique as mesmas operações mostradas aqui.

P: Qual é a diferença entre uint8 e float32 para imagens? R: uint8 (0-255) é o formato padrão para armazenamento e exibição. float32 é usado para computação (filtros, transformações) para evitar overflow e erros de arredondamento.


📖 Resumo

Neste projeto você aplicou:


📝 Exercícios

  1. Básico (Dificuldade ⭐): Troque os canais vermelho e azul da imagem. Que tonalidade isso cria?

  2. Intermediário (Dificuldade ⭐⭐): Implemente um detector de bordas verticais subtraindo colunas adjacentes em vez de linhas. Compare os resultados.

  3. Desafio (Dificuldade ⭐⭐⭐): Implemente um filtro de desfoque simples: substitua cada pixel pela média de sua vizinhança 3x3. Use broadcasting e slicing — sem loops.

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%