Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MATLAB Image Processing - Find Edge and Area of Image

As a preface: this is my first question - I've tried my best to make it as clear as possible, but I apologise if it doesn't meet the required standards.

As part of a summer project, I am taking time-lapse images of an internal melt figure growing inside a crystal of ice. For each of these images I would like to measure the perimeter of, and area enclosed by the figure formed. Linked below is an example of one of my images:

enter image description here

The method that I'm trying to use is the following:

  1. Load image, crop, and convert to grayscale
  2. Process to reduce noise
  3. Find edge/perimeter
  4. Attempt to join edges
  5. Fill perimeter with white
  6. Measure Area and Perimeter using regionprops

This is the code that I am using:

clear; close all;

% load image and convert to grayscale
tyrgb = imread('TyndallTest.jpg');
ty    = rgb2gray(tyrgb);
figure; imshow(ty)

% apply a weiner filter to remove noise.
% N is a measure of the window size for detecting coherent features
N=20;
tywf  = wiener2(ty,[N,N]);
tywf = tywf(N:end-N,N:end-N);

% rescale the image adaptively to enhance contrast without enhancing noise
tywfb = adapthisteq(tywf);

% apply a canny edge detection
tyedb = edge(tywfb,'canny');

%join edges
diskEnt1 = strel('disk',8); % radius of 4
tyjoin1 = imclose(tyedb,diskEnt1);
figure; imshow(tyjoin1)

It is at this stage that I am struggling. The edges do not quite join, no matter how much I play around with the morphological structuring element. Perhaps there is a better way to complete the edges? Linked is an example of the figure this code outputs:

enter image description here

The reason that I am trying to join the edges is so that I can fill the perimeter with white pixels and then use regionprops to output the area. I have tried using the imfill command, but cannot seem to fill the outline as there are a large number of dark regions to be filled within the perimeter.

Is there a better way to get the area of one of these melt figures that is more appropriate in this case?

As background research: I can make this method work for a simple image consisting of a black circle on a white background using the below code. However I don't know how edit it to handle more complex images with edges that are less well defined.

clear all
close all
clc

%% Read in RGB image from directory
RGB1 = imread('1.jpg')   ;

%% Convert RPG image to grayscale image
I1 = rgb2gray(RGB1)       ;

%% Transform Image
%CROP
IC1 = imcrop(I1,[74 43 278 285]);

%BINARY IMAGE 
BW1 = im2bw(IC1); %Convert to binary image so the boundary can be traced

%FIND PERIMETER
BWP1 = bwperim(BW1); 
%Traces perimeters of objects & colours them white (1). 
%Sets all other pixels to black (0)
%Doing the same job as an edge detection algorithm?

%FILL PERIMETER WITH WHITE IN ORDER TO MEASURE AREA AND PERIMETER
BWF1 = imfill(BWP1); %This opens  figure and allows you to select the areas to fill with white.

%MEASURE PERIMETER
D1 = regionprops(BWF1, 'area', 'perimeter'); 
%Returns an array containing the properties area and perimeter. 
%D1(1) returns the perimeter of the box and an area value identical to that
%perimeter? The box must be  bounded by a perimeter.
%D1(2) returns the perimeter and area of the section filled in BWF1

%% Display Area and Perimeter data
D1(2)
like image 670
Peter Harvey Avatar asked Aug 22 '13 14:08

Peter Harvey


People also ask

How do I find the edge of an image in Matlab?

BW = edge( I , method ) detects edges in image I using the edge-detection algorithm specified by method . BW = edge( I , method , threshold ) returns all edges that are stronger than threshold . BW = edge( I , method , threshold , direction ) specifies the orientation of edges to detect.

How do you find the area of an image in Matlab?

total = bwarea( BW ) estimates the area of the objects in binary image BW . total is a scalar whose value corresponds roughly to the total number of on pixels in the image, but might not be exactly the same because different patterns of pixels are weighted differently.

How do I find the lines of an image in Matlab?

Find lines in the image using the houghlines function. lines = houghlines(BW,theta,rho,P,'FillGap',5,'MinLength',7); Create a plot that displays the original image with the lines superimposed on it. figure, imshow(rotI), hold on max_len = 0; for k = 1:length(lines) xy = [lines(k).


1 Answers

I think you might have room to improve the effect of edge detection in addition to the morphological transformations, for instance the following resulted in what appeared to me a relatively satisfactory perimeter.

tyedb = edge(tywfb,'sobel',0.012);

%join edges

diskEnt1 = strel('disk',7); % radius of 4
tyjoin1 = imclose(tyedb,diskEnt1);

In addition I used bwfill interactively to fill in most of the interior. It should be possible to fill the interior programatically but I did not pursue this.

% interactively fill internal regions

[ny nx] = size(tyjoin1);
figure; imshow(tyjoin1)
tyjoin2=tyjoin1;
titl = sprintf('click on a region to fill\nclick outside window to stop...')
while 1
   pts=ginput(1)
   tyjoin2 = bwfill(tyjoin2,pts(1,1),pts(1,2),8);
   imshow(tyjoin2)
   title(titl)
   if (pts(1,1)<1 | pts(1,1)>nx | pts(1,2)<1 | pts(1,2)>ny), break, end
end

This was the result I obtained

enter image description here

The "fractal" properties of the perimeter may be of importance to you however. Perhaps you want to retain the folds in your shape.

like image 188
Buck Thorn Avatar answered Sep 30 '22 18:09

Buck Thorn