Em microscopia de partículas e em OCR de placas de carro desgastadas, traços finos ou descontínuos precisam ser “engrossados” para que o reconhecimento funcione. A dilatação morfológica faz exatamente isso: expande regiões claras usando um elemento estruturante \(B\) — a mesma operação implementada em morph.py como mm.dil0(f, B), usada quando \(B\) é plano (sem pesos, só \(0\)/\(1\)). Ver na Figura 4.32 uma simulação deste EP.
4.9.3.1 📋 Diretrizes de Implementação
Dimensões da imagem: Ler os inteiros \(L\) (linhas) e \(C\) (colunas) de \(f\).
Dimensões de \(B\): Ler os inteiros \(L_B\) (linhas) e \(C_B\) (colunas) do elemento estruturante.
Elemento estruturante: Ler a matriz \(B\) com valores \(0\) ou \(1\), linha a linha.
Dados: Ler a matriz \(f\) (a imagem original), linha a linha.
Reflexão: Construir \(B_{ref}\), a versão de \(B\) refletida em \(180°\) (linhas e colunas invertidas) — exatamente como faz mm.dil0 internamente.
Vizinhança sem padding: Para cada pixel \((y,x)\), percorrer as posições \((by,bx)\) de \(B_{ref}\) centradas em \((y,x)\), usando o deslocamento \[
v_y = y + by + o_y,\quad v_x = x + bx + o_x,\quad o_y=-\tfrac{L_B}{2}+0{,}5,\quad o_x=-\tfrac{C_B}{2}+0{,}5
\]Descartar todo \((v_y,v_x)\) fora de \([0,L)\times[0,C)\) — não preencher com zeros.
Mapeamento: Calcular cada pixel de saída como o máximo entre \(f(y,x)\) e todos os \(f(v_y,v_x)\) válidos cuja posição correspondente em \(B_{ref}\) vale \(1\): \[
g(y,x) = \max\Big(f(y,x),\ \max_{\substack{(v_y,v_x)\ \text{válido}\\ B_{ref}(by,bx)=1}} f(v_y,v_x)\Big)
\]
Saída: Exibir a matriz \(g\) com dimensões \(L \times C\).
4.9.3.2 📌 Restrições Computacionais
Sem padding: Jamais inventar vizinhos fora da imagem; usar apenas os que existem de fato.
Reflexão obrigatória:\(B\) deve ser refletido antes de aplicado (é o que diferencia mm.dil0 de uma simples busca por máximo).
Robustez de borda: Se nenhuma posição válida de \(B_{ref}=1\) cair dentro do domínio para um dado pixel, ele mantém seu valor original.
4.9.3.3 🧠 Fundamentação Teórica
Conceito
Significado
Impacto Visual
Dilatação
\(g \geq f\) sempre (extensiva)
Regiões claras crescem, buracos escuros encolhem
\(B\) maior
Vizinhança mais ampla
Crescimento mais agressivo
Reflexão de \(B\)
\(B_{ref}(y,x) = B(-y,-x)\)
Garante a definição formal de Minkowski da dilatação
4.9.3.4 📦 Especificação de Entrada e Saída (VPL)
Entrada:
Linha 1: Inteiro \(L\).
Linha 2: Inteiro \(C\).
Linha 3: Inteiro \(L_B\).
Linha 4: Inteiro \(C_B\).
Próximas \(L_B\) linhas: elementos inteiros (\(0\) ou \(1\)) da matriz \(B\).
Próximas \(L\) linhas: elementos inteiros da matriz \(f\).
Saída:
Matriz \(g\) em \(L\) linhas e \(C\) colunas, valores inteiros separados por espaço.
4.9.3.5 📌 Exemplos
Entrada
Saída
Observação
3
3
3
3
0 1 0
1 1 1
0 1 0
0 0 0
0 9 0
0 0 0
0 9 0
9 9 9
0 9 0
\(B\) em cruz simétrico: ponto isolado se expande em cruz
1
4
1
3
1 1 1
10 200 5 80
200 200 200 80
\(B\) horizontal: cada pixel “puxa” o máximo dos vizinhos da linha
🌱 Simulador EP04_03: Dilatação Plana (mm.dil0)g = f ⊕ B
Alterne o elemento estruturante B (ou selecione os presets) e clique nas células da imagem original f para acender ou apagar pixels.
Elemento Estruturante B (Clique para Alternar 0/1)
Imagem Original f (5×5)
Dilatada g (f ⊕ B)
g(y,x) = max sobre vizinhos válidos de B refletido
Figura 4.32: Simulador EP04_03: Dilatação Binária Plana (g = f ⊕ B)
%%writefile EP04_03.py# Código Python
Writing EP04_03.py
TestSuite("EP04_03.py").run()
✔️ EP04_03.cases já existe em casos/
📋 5 caso(s) carregado(s) de casos/EP04_03.cases
🔍 Testando Python: EP04_03.py
⚠️ EP04_03.py: Arquivo sem conteúdo (menos de 3 linhas). Testes ignorados.