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

Cálculo da área de folhas com MATLAB

Neste exemplo você verá como obter a área de folhas de uma forma prática, sem a necessidade de contar quadradinhos em papel quadriculado (quem já cursou PPM sabe do que se trata…).

Conteúdo

Começando…

Primeiro você precisa de uma foto das folhas e tem que haver uma escala na foto, senão não serve. Eu tenho aqui a foto de folhas de Laguncularia sp. e a escala é o papel milimetrado no fundo.

Começamos abrindo a foto, mas antes esvaziamos o ambiente de trabalho.

clear all; close all; clc;

folhas = imread('original.jpg');
imshow(folhas);
Warning: Image is too big to fit on screen; displaying at 25%

[Original]

Falta algo…

Não dá para obter a área do jeito que a foto está, ele deve estar em preto e branco (só preto e branco, não confunda com escala de cinza) e com o mínimo possível de elementos a mais. Dá para fazer tudo isso direto no MATLAB, mas eu tenho PhotoShop e preguiça, então editei lá mesmo.

Vou abrir a imagem certa.

folhas = imread('editada.png');
imshow(folhas);

[Editada]

esta está certa e eu já marquei um quadrado com 1cm de lado que será minha referência.

Ainda assim, o MATLAB abre a foto como uma matriz tridimensional (largura, altura e canal RGB), mas as funções que usaremos a seguir trabalham com preto e branco puro.

Então removeremos os canais RGB: primeiro juntamos tudo em escala de cinza.

I = rgb2gray(folhas);

e em seguida em preto e branco puro

threshold = graythresh(I);
bw = im2bw(I,threshold);

Agora vamos trabalhar

Agora que temos só o que interessa da imagem, podemos obter o contorno das folhas e de nosso quadrado de referência.

[B,L] = bwboundaries(bw);

Eu quero que cada folha apareça de uma cor, então escolhi o colormap jet e especifiquei que ele deve ser distribuido pelos objetos encontrados pela função bwboundaries (repare que o L aparece aí de novo).

imshow(label2rgb(L, @jet, [.5 .5 .5]));

[Folhas]

Agora basta plotar os contornos das folhas, um de cada vez. Repare que aqui usamos o B que a bwboundaries nos deu, ele representa o limite de cada objeto encontrado. Repare que B é um array de cell, então acessa-se o conteúdo de seus elementos com chaves e não com parênteses.

hold on
for k = 1:length(B)
  boundary = B{k};
  plot(boundary(:,2), boundary(:,1), 'black', 'LineWidth', 2)
end

[Folhas]

Finalmente as áreas

Um comando e pronto…

stats = regionprops(L,'Area');

Apresentação dos dados

Agora é só colocar os números sobre a figura e terminamos.

for k = 1:length(B)
  % obtem (X,Y) do contorno k
  boundary = B{k};
  % A área do contorno k
  area = stats(k).Area;
  % o resto é óbvio, né?
  area_string = sprintf('%.0f',area);
  text(boundary(1,2)+5,boundary(1,1)+13,area_string,...
      'Color','white',...
      'FontSize',8,...
      'FontWeight','bold',...
      'BackgroundColor','black',...
      'FontName','Times');
end

hold off

[Folhas]

Observações

O mais importante é destacar que a área está em pixels, e, para converter de pixels para centímetros quadrados, basta usar a área em pixels da referência (no meu caso, 441). Como a minha referência era um quadrado de um centímetro de lado, eu apenas dividi todos os valores em pixels por 441 e obtive áreas em centímetros quadrados.

Você pode reparar que o MATLAB obteve as áreas dos buracos também, mas você não precisa se preocupar com elas, a área da folha que aparece já desconta os buracos.