Aula 1 — Fundamentos de Imagem Digital e Representação em Memória (PDI)¶
Nesta aula você vai consolidar a teoria mínima necessária para executar o notebook prático:
O objetivo não é decorar termos, mas entender como a imagem é representada e o que acontece quando você lê, visualiza e altera pixels.
Como usar este handout¶
Fluxo recomendado
- Antes do notebook: leia até a seção 5 e responda os quizzes conforme aparecem.
- Durante o notebook: use este material como referência (principalmente BGR/RGB,
shape,dtype,resize). - Depois (5 min): revise apenas as perguntas que errou e valide no código.
Objetivos de aprendizagem¶
Ao final desta aula, você deve ser capaz de:
- Explicar o que significa uma imagem ser um sinal discreto 2D (amostragem + quantização).
- Interpretar a estrutura de uma imagem em Python como arrays NumPy (
H×W×C). - Diferenciar BGR (OpenCV) de RGB (Matplotlib) e evitar visualização “com cores erradas”.
- Identificar
dtype(ex.:uint8) e o range de valores que ele suporta. - Aplicar operações simples: tons de cinza, resize/amostragem, leitura de pixel, alteração de pixels.
- Entender por que varrer imagem com
foré lento e quando isso faz sentido.
1) Imagem digital: amostragem e quantização¶
Uma imagem digital pode ser vista como um sinal contínuo (mundo real) convertido em uma estrutura discreta:
- Amostragem (sampling): define quantos pixels teremos (resolução).
- Quantização (quantization): define quantos valores possíveis cada pixel pode assumir.
Em termos práticos:
- Mais resolução ⇒ mais detalhes espaciais, mas maior custo de processamento.
- Mais bits por pixel ⇒ mais níveis de intensidade (ex.: 8 bits ⇒ 256 níveis).
Qual definição descreve melhor amostragem em imagens?
Uma imagem de 8 bits por pixel tem quantos níveis possíveis de intensidade?
2) Como a imagem aparece no código (NumPy)¶
No notebook, após carregar uma imagem, você verá algo como:
- Imagem em tons de cinza: array 2D
shape = (H, W) - Imagem colorida: array 3D
shape = (H, W, C)comC = 3(canais)
Interpretação:
H= número de linhas (altura)W= número de colunas (largura)C= canais de cor
Regra prática de indexação
Em NumPy/OpenCV você acessa como img[y, x] (linha primeiro, coluna depois).
Ou seja: (y, x) ≈ (linha, coluna).
Em NumPy/OpenCV, se img.shape == (720, 1280, 3), o que isso significa?
Qual acesso é correto para pegar um pixel na posição (x=50, y=10) em NumPy/OpenCV?
3) BGR vs RGB: por que as cores “ficam erradas”?¶
- OpenCV (
cv2) lê imagens em BGR (Blue, Green, Red). - Matplotlib (
plt.imshow) espera RGB.
Se você fizer:
as cores provavelmente ficarão trocadas.A correção é converter:
Pegadinha clássica
Se você não converter BGR→RGB, seu pipeline pode “parecer” errado, mas o problema é apenas de visualização (não necessariamente do processamento).
Qual é a ordem padrão de canais ao carregar uma imagem com cv2.imread()?
Para visualizar corretamente no Matplotlib uma imagem lida pelo OpenCV, você normalmente faz:
4) Tons de cinza: o que muda?¶
Uma imagem em tons de cinza pode ser vista como uma única banda de intensidade.
No OpenCV:
cv2.imread(path, cv2.IMREAD_GRAYSCALE)- ou
cv2.imread(path, 0)
Na visualização com Matplotlib, use:
Por que usar cmap='gray'?
Sem o cmap, o Matplotlib pode aplicar um mapa de cores (colormap) que não representa “cinza” de verdade, o que atrapalha sua interpretação.
No OpenCV, carregar uma imagem diretamente em tons de cinza pode ser feito com:
Ao usar plt.imshow() para mostrar uma imagem em tons de cinza, o mais correto é:
5) Tipos (dtype) e range: por que isso importa?¶
A maioria das imagens lidas com OpenCV vem como:
dtype = uint8- valores no range [0, 255]
Isso tem consequências:
- Ao fazer contas, você pode ter overflow ou clipping se não controlar o tipo.
- Para operações matemáticas (ex.: normalização, filtros, gamma), é comum converter para
float32, calcular e depois voltar parauint8com recorte.
Exemplo de boa prática (ideia geral):
img_f = img.astype("float32") / 255.0
# ... processa ...
img_u8 = (img_f * 255).clip(0, 255).astype("uint8")
Uma imagem uint8 tipicamente tem valores de intensidade entre e .
Qual é o motivo mais comum para converter uma imagem para float32 antes de certas operações?
6) Amostragem na prática: resize e interpolação¶
No notebook, você usa cv2.resize() para mudar o tamanho:
Dois pontos importantes:
- O tamanho é informado como (largura, altura) — atenção: é o inverso do
shape. -
A interpolação define como os novos pixels são estimados:
-
INTER_NEAREST: rápido, pode “pixelar” INTER_LINEAR: padrão, bom para muitos casosINTER_AREA: geralmente bom para reduzir (downsample)
O cv2.resize(img, (600, 400), ...) recebe o tamanho no formato:
Qual interpolação tende a ser boa para reduzir a imagem (downsample)?
7) Acessando e alterando pixels¶
Acesso a um pixel (colorido):
Acesso a um pixel (cinza):
Alterar pixels pode ser feito com for, mas isso é caro:
Custo computacional
Uma imagem 1080p tem ~2 milhões de pixels.
Dois for aninhados em Python ficam lentos rapidamente.
Alternativa profissional: usar operações vetorizadas (NumPy) e máscaras. Você verá isso nas próximas aulas.
Marque as afirmativas verdadeiras sobre varrer uma imagem com for em Python: