5.14. Suavização Gaussiana e arestas

Dois trabalhos dominam o uso de janelas de vizinhança na visão por computador clássica: suavizar a variação pixel a pixel de forma limpa, e encontrar as arestas onde a imagem muda abruptamente. O filtro Gaussiano é a ferramenta padrão para o primeiro, os detetores baseados no Laplaciano a ferramenta padrão para o segundo – e os dois compõem-se, porque cada detetor de arestas funciona melhor num input levemente suavizado.

5.14.1. O filtro Gaussiano

gaussian() é o primo ponderado pelo centro de mean(). Ambos calculam uma média sobre a vizinhança de cada pixel, mas os pesos do Gaussiano não são uniformes: os pixels mais próximos do centro da vizinhança contam mais, os pixels na borda da vizinhança contam menos, com os pesos seguindo a familiar curva em sino que dá ao filtro o seu nome.

A ponderação em forma de sino é o que torna um filtro Gaussiano mais suave do que uma média de caixa. A filtragem pela média pode produzir artefactos visíveis nas arestas dos objetos – um corte abrupto na ponderação introduz pequenos padrões de oscilação em transições nítidas. Os pesos de queda suave do Gaussiano evitam essa oscilação e produzem um resultado que se parece mais com o que «desfocado» deveria parecer. O custo é mais cálculo por pixel do que o filtro de média, mas não dramaticamente – o custo por pixel ainda é muito inferior ao do filtro bilateral.

img.gaussian(1)    # 3x3 Gaussian -- a clean light blur
img.gaussian(2)    # 5x5 Gaussian -- stronger smoothing

A suavização Gaussiana é a primeira etapa padrão de quase todos os pipelines de deteção de arestas. Os detetores de arestas abaixo amplificam todos o conteúdo de alta frequência, incluindo o ruído do sensor que o algoritmo não quer realmente detetar. Executar um Gaussiano leve primeiro suprime esse ruído sem suavizar muito as arestas reais, deixando o detetor de arestas encontrar arestas reais em vez de manchas.

5.14.2. Máscara de desfoque inverso

Uma cópia desfocada pelo Gaussiano de uma imagem é o material bruto que a técnica de máscara de desfoque inverso usa para a nitidez clássica. Definir unsharp=True no filtro muda-o de «produzir a imagem desfocada» para «subtrair a imagem desfocada do original e adicionar a diferença de volta ao original» – o efeito é que as arestas de alta frequência são amplificadas em relação aos interiores suaves.

img.gaussian(1, unsharp=True)

Os parâmetros opcionais mul e add escalam a intensidade do resultado da máscara de desfoque inverso; os valores predefinidos (mul=1.0, add=0.0) correspondem a uma nitidez moderada que não exagera o ruído do sensor.

5.14.3. O filtro Laplaciano

laplacian() executa uma aproximação discreta da segunda derivada espacial da imagem. O output é grande onde os valores de pixel mudam rapidamente, próximo de zero onde são constantes ou mudam linearmente. A leitura natural do resultado é uma resposta de aresta: os pixels onde a imagem muda rapidamente iluminam-se, os pixels em interiores suaves ficam escuros.

img.laplacian(1)   # 3x3 Laplacian -- edge response

Os mesmos parâmetros que gaussian estão disponíveis. sharpen=True produz uma imagem com mais nitidez (o Laplaciano adicionado de volta ao original em vez de devolvido sozinho). mul e add escalam a resposta.

Um uso prático além da deteção de arestas é a medição de foco. A resposta do Laplaciano calculada em média numa região fornece uma medida aproximada de quanto conteúdo de alta frequência a região contém; num fotograma bem focado essa média é alta, num fotograma desfocado diminui. Comparar a resposta do Laplaciano entre fotogramas é a forma económica de perguntar «a lente está focada?» sem precisar de uma métrica de contraste mais cara.

5.14.4. O método find_edges

find_edges() executa um pipeline completo de deteção de arestas em vez de apenas um filtro de resposta de aresta. Funciona em imagens em escala de cinzentos, e o resultado é uma imagem binária cujos pixels não nulos marcam as posições onde o input tem o tipo de mudança de brilho que deve contar como uma aresta.

O método aceita um parâmetro edge_type que escolhe entre dois algoritmos:

EDGE_SIMPLE executa um filtro passa-alto, aplica um limiar e devolve o resultado. Rápido, mas o output inclui todas as mudanças de brilho acima do limiar, incluindo ruído e textura com que a aplicação provavelmente não se preocupa. Razoável para imagens limpas e para casos em que o ruído será eliminado por uma passagem morfológica posterior.

EDGE_CANNY executa o detetor de arestas Canny – o algoritmo clássico de múltiplas etapas. Calcula o gradiente de brilho, suprime cada resposta não-máxima ao longo da direção do gradiente (de modo que cada aresta tenha um pixel de largura) e aplica um limiar por histerese (de modo que uma aresta que é forte num lugar seja traçada mesmo onde se esbate). O resultado é um conjunto limpo, fino e contínuo de pixels de aresta do tipo que todos os algoritmos clássicos baseados em arestas pretendem.

O parâmetro threshold é uma tupla de dois elementos (low, high). Para EDGE_CANNY, o valor high é o limite acima do qual um pixel é definitivamente uma aresta, e o valor low é o limite acima do qual um pixel é uma aresta apenas se estiver ligado a uma definitiva. Para EDGE_SIMPLE, apenas o valor high importa; é o único limite acima do qual um pixel conta como aresta. O valor predefinido de (100, 200) é um ponto de partida que vale a pena ajustar para a cena específica.

img.gaussian(1)                                   # pre-smooth
img.find_edges(image.EDGE_CANNY, threshold=(50, 100))

O detetor Canny é a melhor escolha para quase todas as aplicações onde as arestas são importantes. O mais rápido EDGE_SIMPLE vale a pena recordar para os casos em que o custo do Canny é um problema e a rejeição de ruído da sua histerese não é realmente necessária.

5.14.5. Limiar adaptativo no Gaussiano

Tal como os filtros estatísticos, gaussian() aceita o par de palavras-chave threshold=True / offset=N para limiar adaptativo. O comportamento é o mesmo que com mean(): a estatística Gaussiana em cada posição torna-se o limite local, e o pixel de origem é comparado com a estatística mais o deslocamento para produzir um resultado binário.

A variante Gaussiana é geralmente a escolha mais limpa para limiar adaptativo quando o input tem relativamente pouco ruído. A média ponderada fornece um limite mais suave do que o filtro de média produz, com menos artefactos em transições de iluminação abruptas.