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…).
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%
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);
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 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]));
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
Um comando e pronto…
stats = regionprops(L,'Area');
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
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.