Image Processing Edge Detection

8 views (last 30 days)
Caroline
Caroline on 26 Jan 2020
Edited: Image Analyst on 27 Jan 2020
Hello,
I am having problems with image processing. I am trying to get matlab to find the outline of images of crystals - code is attached. I am having problems with some images as not all sides of the crystal are found. You can see in the first set of images where the edges have been correctly found and so the shape has been filled in, where as in the second it has only found part of the edge.
So far I have tried sharpening the image, altering the contrast and changing the structuring element to close the shape with no success.
Any help with this would be greatly appreciated.
Attatched:
Image of crystal
Code I am using
Example of the resuts of the code working correctly and not.
1_0_0_1.bmp
Figure 1 code working correctly.png
Figure 1 code not working correctly.png

Answers (2)

Turlough Hughes
Turlough Hughes on 26 Jan 2020
Edited: Turlough Hughes on 26 Jan 2020
You could try the following modification. The main thing I did was use bwareafilt to filter out all but the largest area, then following that up with imclose but using a larger strel.
%reset work space etc.
clear
clc
close all
%find image files in folder
folder = '../4/';
fileList = dir([folder,'*.bmp']);
fileNames = [{fileList(:).name}];
sorted_filenames=natsortfiles(fileNames);
C=[];
fontSize = 12;
for i =1:3
im = imread([sorted_filenames{i}]);
figure(1);
set(gcf,'Position', [250 400 600 400])
subplot(2,2,1)
imshow(im);
BW = ~imbinarize(im);
A1 = bwareafilt(BW,1); % filter all but the largest component
subplot(2,2,2)
imshow(A1)
title('Otsu Threshold & bwareafilt','fontSize',fontSize)
se=strel('disk',200); % modified
A2=imclose(A1,se);
subplot(2,2,3), imshow(A2)
title('Resulting image from imclose','fontSize',fontSize)
s=regionprops(A2,{'Centroid',...
'MajorAxisLength',...
'MinorAxisLength',...
'Orientation'});
centroids=cat(1,s.Centroid);
subplot(2,2,4);
imshow(A2,'InitialMagnification','fit')
hold on
plot(centroids(:,1),centroids(:,2),'b*')
hold off
t = linspace(0,2*pi,50);
hold on
for k = 1:length(s)
a = s(k).MajorAxisLength/2;
b = s(k).MinorAxisLength/2;
Xc = s(k).Centroid(1);
Yc = s(k).Centroid(2);
phi = deg2rad(-s(k).Orientation);
x = Xc + a*cos(t)*cos(phi) - b*sin(t)*sin(phi);
y = Yc + a*cos(t)*sin(phi) + b*sin(t)*cos(phi);
plot(x,y,'r','Linewidth',5)
end
hold off
end

Image Analyst
Image Analyst on 26 Jan 2020
Edited: Image Analyst on 27 Jan 2020
I would use bwconvhull() to close the shape rather than imclose(). bwconvhull() does not depend on picking the proper size of any structuring element like imclose() does.
Then, to get the coordinates of the outlines, you can use bwboundaries():
binaryImage = bwconvhull(binaryImage,'objects');
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
% Plot the borders of all the coins on the original grayscale image using the coordinates returned by bwboundaries.
imshow(originalImage);
title('Outlines, from bwboundaries()', 'FontSize', 14);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.
boundaries = bwboundaries(binaryImage);
numberOfBoundaries = size(boundaries, 1);
hold on;
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'g-', 'LineWidth', 2);
end
hold off;

Categories

Find more on Biomedical Imaging in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!