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

Isóbatas e superfícies a partir de pontos no papel

Conteúdo

Introdução

O objetivo deste programa é desenhar isóbatas a partir de pontos plotados no papel. Partiremos de uma imagem como a logo abaixo (contendo pontos e as respectivas profundidades em metros) e obteremos a superfície que estes pontos representam.

[inicio]

Princípios

Para atingirmos o objetivo, seguiremos as seguintes etapas

  • Pré processamento: nesta etapa será feita a correção das cores e recortes, se necessário;
  • Extração das propriedades de interesse: obteremos as propriedade de interesse dos objetos existentes na imagem;
  • Reconhecimento de formas: através das relações entre as propriedade obtdas no item anterior, serão identificadas as formas de interesse, no caso, círculos.
  • Obtenção das profundidades: serão obtidas as profundidades correspondentes a cada ponto.
  • Visualização dos resultados: plotaremos os contornos (objetivo principal) e também plotaremos a superfície correspondente.
close all; clear all; clc;

Pré processamento da imagem

Lê a imagem

orig = imread('IMG_0046.JPG');

% Converte a imagem para preto e branco puro: a função im2bw converte para
% escala de cinza e torna brancos todos os pixels com luminância maior
% que 0.4,isso reduz o efeito da má iluminação usada na foto original.
bw = im2bw(orig,0.4);

% Inverte as cores (preto e branco).
bw = ~bw;

Extração das propriedades de interesse

Localiza as bordas dos objetos existentes na imagem. Nesse caso eu sei que não há buracos nos objetos que me interessam, então posso usar a opção 'noholes'.

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

% Com base nas bordas, calcula os centroides e as áreas dos objetos.
stats = regionprops(L,'Area','Centroid','Perimeter');

Reconhecimento de formas

Esse é o limite mínimo de o quão redondo são os circulos que me interessam (1 representa um círculo perfeito).

lim = 0.8;

u = 1;
coord = zeros(47, 2);
for k = 1:length(B)
    % Seleciona uma das bordas
    boundary = B{k};
    perimeter = stats(k).Perimeter;
    area = stats(k).Area;

    % metric recebe um valor que indica o quão redondo é o círculo (esse
    % tipo de relação está na internet: é só copiar).
    metric = 4*pi*area/perimeter^2;

    % Se o objeto for suficentemente circular e tiver uma área mínima...
    if (metric > lim) && (area > 50)
        centroid = stats(k).Centroid;
        % Armazena o centroide, ele será útil mais adiante
        coord(u,:) = [centroid(1) centroid(2)];
        u = u+1;
    end
end

Obtenção das profundidades

Isso é trapaça, aqui eu poderia treinar uma rede neural para identificar as profundidades automaticamente, mas eu preferi digitar. Os leitores são encorajados a tentar a abordagem via rede neural, há um ótimo exemplo no MATLAB File Exchange.

prof = [105 90 70 90 80 52 60 75 70 66 60 55 75 75 50 45 75 70 60 80 80 ...
        50 70 95 66 65 73 78 60 51 88 64 54 40 71 75 102 70 80 55 60 90 ...
        104 25 45 55 46];
coord(:,3) = prof;

Visualização dos resultados

Cria uma grade para os dados (o objetivo desse programa é obter contornos com a função contour, que só funciona com dados em grade).

[h w] = size(bw);
[xx yy] = meshgrid(1:w, 1:h);

% Ajusta os dados à grade
zz = griddata(coord(:,1), coord(:,2),prof,xx,yy,'cubic');

% O código abaixo plota os contornos e os pontos
ah(1) = figure;
imshow(orig);
hold on
plot(coord(:,1),coord(:,2),'or','MarkerFaceColor','r');
[C h] = contour(xx,yy,zz);
th = clabel(C,h);
set(th,'BackgroundColor',[1 1 .6]);
hold off
colormap(jet);

% O código abaixo plota a superfície
ah(2) = figure;
meshc(xx,yy,zz);
axis ij; view(-4,38);
colorbar vert;

set(ah,'color','w');
Warning: Image is too big to fit on screen; displaying at 50%

[isobatas]

superficie