Médias, Medianas e Imagens

Medidas de tendência central (média, mediana, moda, etc.) estão entre os primeiros conceitos que aprendemos em qualquer curso introdutório de estatística. Esses conceitos vêm acompanhados de diversos exemplos como: qual é a média de altura da turma (ou idade, ou coisas mais delicadas como peso), ou a média/mediana dos salários de uma determinada empresa. Esses conceitos são fundamentais para entendermos melhor o mundo ao nosso redor. Neste post, entretanto, o objetivo não é explicar nem os conceitos, nem por que são importantes, mas responder à pergunta: mas e a computação nisso?

Uma aplicação bastante direta é calcular o tempo médio de execução de um determinado algoritmo, o que pode nos ajudar a assimilar os conceitos de notação assintótica (por exemplo, O-grande - O(1), O(N), O(NlogN)), por exemplo. Se você não tem ideia do que significam esses conceitos, não se preocupe. Por ora, gostaria de focar em outra aplicação: processamento de imagens.

Imagens digitais

Antes de apresentar a aplicação propriamente dita, vamos fazer uma breve revisão do que é uma imagem digital. A forma mais comum de se representar uma imagem em um computador é como uma tabela, ou matriz, de pixels. Um pixel é simplesmente uma representação de uma determinada cor, em uma imagem colorida, ou intensidade, em uma imagem em níveis de cinza (popularmente chamadas também de imagem em preto e branco). Por questão de simplicidade vamos trabalhar somente com imagens em níveis de cinza. A maioria das imagens em níveis de cinza possui 256 tons (não, não são 50) variando do preto (0) ao branco (255).

Imagem em níveis de cinza

Uma imagem em níveis de cinza é então simplesmente uma tabela de números entre 0 e 255:

Lena com zoom

Médias em imagens

Voltando às medidas de tendência central. Como a imagem é simplesmente uma tabela de números é possível calcular a sua média. Por exemplo, a média da imagem acima é 91,52. Não diz muito, certo? Ao invés disso, vamos considerar somente uma linha:

Preto e branco

Se substituirmos cada pixel pela média de seus vizinhos (os pixels à esquerda e à direita, quando existirem) e o próprio pixel obtemos o seguinte resultado:

Média de 2 vizinhos

A média nesse caso fez com que a diferença entre pixels adjacentes fosse suavizada! O resultado visual é uma suavização das bordas, deixando a imagem mais borrada. Vejamos o que acontece se considerarmos dessa vez 5 pixels na média (2 pixels à esquerda, 2 pixels à direita e o próprio pixel):

Média de 4 vizinhos

O processo de aquisição e armazenamento de imagens não é perfeito. Assim, é comum a ocorrência de ruído na imagem. Vamos considerar um caso simples, com uma linha de pixels pretos. Vamos adicionar ruído aleatoriamente: um dos pixels que deveria ser preto foi registrado como branco.

Linha com ruído

Vamos repetir o processo de calcular a média para os 5 pixels vizinhos:

Ruído filtrado com média

Como a maior parte dos pixels é da mesma cor, a média tende a se aproximar à cor da maioria, no caso o preto. Assim, a intensidade do pixel branco é reduzida. Em outras palavras, esse processo pode ser utilizado para reduzir o ruído de uma imagem. Um efeito colateral é que o ruído acaba se “diluindo”, afetando os pixels vizinhos, inicialmente na cor certa. Esse processo de substituição de um pixel pela média dos seus vizinhos é conhecido como filtro de média.

Vamos adicionar uma dimensão extra. Agora a média será calculada entre os todos os vizinhos de cada pixel, ou seja, ao invés de considerar somente os pixels dos lados agora também consideraremos os pixels acima, abaixo e nas diagonais.

Vizinhança 2D

Na imagem mostrada acima o pixel 35 será substituído pela média dos seus vizinhos, ou seja, (23 + 233 + 103 + 134 + 35 + 65 + 240 + 123 + 54)/9 = 112,22. O efeito será exatamente o mesmo observado em uma única linha. Vamos voltar à nossa imagem original e adicionar ruído aleatório (pixels brancos e pretos em posições aleatórias - ou ruído sal e pimenta).

Lena com ruído

Aplicando então o filtro de média usando os 8 vizinhos e o próprio pixel obtemos o seguinte resultado:

Lena filtrada (3x3)

O conjunto de pixels considerados na média é chamado de janela. A quantidade de pixels na janela pode ser maior do que 9. Não há limites para o tamanho e nem para a forma da janela. A seguinte imagem mostra a aplicação de um filtro de média com 49 pixels na janela (um quadrado de 7 por 7 pixels).

Lena filtrada (7x7)

Inclusive, no caso extremo consideramos uma janela bem grande (maior do que a própria imagem). Assim cada pixel será substituído pela média dos pixels da imagem, que na imagem com ruído é 91,67, produzindo a seguinte imagem com um único tom de cinza:

Lena filtrada com kernel gigante

Medianas em imagens

O que aconteceria se simplesmente trocássemos a média por uma mediana? Vamos primeiro considerar uma propriedade das medianas. A mediana do conjunto {0, 1, 100} é 1. Não importa o quão grande seja o último número e nem o quão pequeno seja o primeiro número. Da mesma forma, o número 255 não faz diferença no cálculo da mediana do conjunto {0, 0, 0, 0, 255}, que continuará sendo 0, independente do que colocarmos no lugar do 255. Isso não é verdade no caso da média. Assim, no exemplo da linha com um pixel branco o resultado da aplicação do filtro de mediana seria (usando uma janela de tamanho 5 - dois à esquerda e dois à direita):

Ruído filtrado com mediana

Vejamos o que acontece com a linha metade preta e metade branca:

Filtro em linha preto e branca

Esse exemplo mostra uma propriedade interessante dos filtros de mediana. Enquanto o filtro de média borra a imagem inteira, suavizando as bordas, o filtro de mediana preserva as bordas. Vejamos o que acontece ao aplicarmos o filtro de mediana na imagem com ruído (janela de 3 por 3 pixels):

Lena filtrada com mediana

A desvantagem do uso de filtros de mediana ao invés de média é a sua maior complexidade computacional. Enquanto o cálculo da média é linear (O(N)) no número de pixels (basta somar todos os valores e dividir pela quantidade), o cálculo da mediana consome O(NlogN) (é necessário ordenar os valores dos pixels e devolver o central).

Outra explicação para o efeito de filtros de média em uma imagem utiliza a transformada de Fourier. Acho essa explicação particularmente bonita, mas deixo ela para algum post futuro.