title: MATLAB Image Processing - Find Edge and Area of Image
body: <p>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.</p>
  
  <p>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:</p>
  
  <p><img src="https://i.stack.imgur.com/j8o2K.jpg" alt="enter image description here"></p>
  
  <p>The method that I'm trying to use is the following:</p>
  
  <ol>
  <li>Load image, crop, and convert to grayscale</li>
  <li>Process to reduce noise</li>
  <li>Find edge/perimeter</li>
  <li>Attempt to join edges</li>
  <li>Fill perimeter with white</li>
  <li>Measure Area and Perimeter using regionprops</li>
  </ol>
  
  <p>This is the code that I am using:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>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:</p>
  
  <p><img src="https://i.stack.imgur.com/DLEYm.jpg" alt="enter image description here"></p>
  
  <p>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. </p>
  
  <p>Is there a better way to get the area of one of these melt figures that is more appropriate in this case?</p>
  
  <p>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.</p>
  
  <pre><code>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 &amp; 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)
  </code></pre>