Danilo R. Vieira | Oceanógrafo

Aqui estão algumas das coisas que eu aprendi, descobri ou fiz (por obrigação ou por diversão). Espero que encontre algo que seja útil para você.

MATLAB → Manipulação e análise de imagens

Uma breve introdução ao processamento de imagens em MATLAB

O MATLAB lê imagens como matrizes (de pixels). Então a manipulação de imagens fica bastante fácil. Neste tutorial, utilizaremos as funções da Image Processing Toolbox. O código foi testado em MATLAB 7.9.0 (R2009b), mas é provável funcione em versões anteriores (ou não). Além deste artigo que você está lendo, há mais sobre processamento de imagens neste site, tem o artigo que mostra como calcular áreas em objetos que aparecem nas imagens e outro que integra imagens a interfaces gráficas.

Neste exemplo, utilizaremos o MATLAB para contar objetos de uma certa cor em uma imagem e calcular o perímetro desses objetos.

O primeiro passo é abrir o arquivo. Isso é feito com a função imopen, que recebe o nome do arquivo como parâmetro. O seguinte código pode ser usado para abrir uma imagem no MATLAB:

original = imread('lego.png');

Assim, a variável original conterá a imagem como uma matriz. Você pode observar que a quantidade de linhas e colunas corresponde à altura e largura da imagem (em pixels) respectivamente. Entretanto, você verá que existe uma terceira dimensão na matriz, isso ocorre, pois cada um dos canais RGB (vermelho, verde e azul na sigla em inglês) são armazenados separadamente. A combinação desses canais produz todas as cores possíveis. Essa separação em canais facilita processamentos que dependem de uma cor específica, como veremos a seguir. Vale lembrar que, no caso de algumas imagens em escala de cinza ou mesmo coloridas com cores indexadas, essa dimensão extra não aparece (não trataremos deste caso neste artigo).

Agora podemos já podemos visualizar a imagem, vamos usar a função imshow. Observe como o MATLAB cuida se encarrega de combinar os canais RGB e mostrar as cores corretamente.

imshow(original);

Vamos fazer algo útil. Começaremos contando quantos objetos azuis há na foto. O primeiro passo é verificar quais pixels tem menos vermelho (canal 1). No caso utilizei o valor 90, mas você deve testar um valor que dê melhores resultados com suas imagens.

azuis = original(:,:,1) < 90;
imshow(azuis);

Agora podemos identificar quais objetos há nessa foto. Para isso usamos a função bwboundaries. Essa função identifica os objetos presentes em uma imagem em preto e branco (binária):

[B,L] = bwboundaries(azuis, 'noholes');

A função bwboundaries retorna duas variáveis: a primeira representa os contornos dos objetos, a segunda é uma matriz de índices em que cada elemento da matriz é um inteiro indicando de qual objeto esse elemento da matriz faz parte. Se não ficou claro o que é a segunda variável, pense nela como uma representação dos objetos na foto.

Agora com os objetos identificados, contamos quantos objetos há na foto. Como a foto está com muito ruído, calcularemos a área dos objetos para desconsiderar objetos com área muito pequena. O cálculo da área é feito com a função regionprops, que também calcula perímetro, inclinação e muitas outras coisas (consulte a documentação para saber mais).

stats = regionprops(L, 'Area');
qtd_azuis = sum([stats.Area] > 50);
qtd_azuis =

     4

Temos nossos resultados, mas precisamos de uma forma mais eficiente de exibi-los. O código a seguir faz isso, plotando os contornos obtidos pela função bwboundaries e exibindo as áreas calculadas pela função regionprops.

imshow(original);
title(sprintf('\\fontsize{16}{Existem %d objetos azuis nessa imagem}', qtd_azuis));

hold on
for k = 1:length(B)
    area = stats(k).Area;

    if area > 50
        boundary = B{k};
        plot(boundary(:,2), boundary(:,1), 'black', 'LineWidth', 2);
        text(boundary(1,2), boundary(1,1), sprintf('%.0f',area),...
            'Color', 'white',...
            'FontSize', 12,...
            'FontWeight', 'bold',...
            'BackgroundColor', 'black');
    end
end
hold off

Assim encerramos o artigo. Tenha em mente que a função regionprops faz muito mais que isso, ela pode calcular a inclinação, área, perímetro, centróide e diversos outros parâmetros.