# detect certain shapes in binary

Asked by Tulips on 3 Jul 2012
Latest activity Commented on by Image Analyst on 31 Jul 2012

hi,in my image has 2 shapes ;triangular and circular(in binary). how can I eliminate the circular shape so that it just detect triangular shape.many thanks!

## Products

No products are associated with this question.

## 2 Answers

Answer by Walter Roberson on 3 Jul 2012
Accepted answer

Use regionprops() to calculate the Eccentricity. Eccentricity should be nearly 0 for a circle.

## 16 Comments

Image Analyst on 6 Jul 2012

See my image segmentation tutorial. http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862 It's done in there, and very well documented about how you use ismember() to filter out objects based on certain criteria.

Tulips on 6 Jul 2012

sir,which file should I refer to?there are a lot..

Walter Roberson on 6 Jul 2012

http://www.mathworks.com/matlabcentral/fileexchange/25157-image-segmentation-tutorial-blobsdemo/content/BlobsDemo.m

Look for the line that says

```% Now I'll demonstrate how to select certain blobs based using the ismember function.
```
Answer by Image Analyst on 3 Jul 2012
Edited by Image Analyst on 9 Jul 2012

I prefer the perimeter squared to area ratio - the "circularity". For things like an asterisk shape, the eccentricity would be similar to similar to a circle bit the "circularity" of an asterisk would be much higher than that of a circle.

```circularity = perimeter^2 / (4 * pi * area);
```

This is a very commonly used metric in shape analysis. So common that I don't know why it's not built into regionprops(). See my shape recognition demo:

```% Demo to find certain shapes in an image based on their shape.
clc;    % Clear the command window.
close all;  % Close all figures (except those of imtool.)
imtool close all;  % Close all imtool figures.
clear;  % Erase all existing variables.
workspace;  % Make sure the workspace panel is showing.
fontSize = 20;
```
```% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'pillsetc.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there.  Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it.  Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
```
```% Read in image into an array.
rgbImage = imread(fullFileName);
[rows, columns, numberOfColorBands] = size(rgbImage);
% Display it.
subplot(2, 2, 1);
imshow(rgbImage, []);
title('Input Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Shape Recognition Demo','numbertitle','off')
```
```% If it's monochrome (indexed), convert it to color.
if numberOfColorBands > 1
grayImage = rgbImage(:,:,2);
else
% It's already a gray scale image.
grayImage = rgbImage;
end
```
```% Make a triangle on it.
triangleXCoordinates = [360 420 480];
triangleYCoordinates = [350 252 350];
traiangleBinaryImage = poly2mask(triangleXCoordinates, triangleYCoordinates, rows, columns);
% Burn it into the gray scale image.
grayImage(traiangleBinaryImage) = 255;
```
```% Display it.
subplot(2, 2, 2);
imshow(grayImage, []);
title('Grayscale Image', 'FontSize', fontSize);
```
```% Binarize the image.
binaryImage = grayImage > 120;
% Display it.
subplot(2, 2, 3);
imshow(binaryImage, []);
title('Initial (Noisy) Binary Image', 'FontSize', fontSize);
```
```% Remove small objects.
binaryImage = bwareaopen(binaryImage, 300);
% Display it.
subplot(2, 2, 4);
imshow(binaryImage, []);
title('Cleaned Binary Image', 'FontSize', fontSize);
```
```[labeledImage numberOfObjects] = bwlabel(binaryImage);
blobMeasurements = regionprops(labeledImage,...
'Perimeter', 'Area', 'FilledArea', 'Solidity', 'Centroid');
```
```% Get the outermost boundaries of the objects, just for fun.
filledImage = imfill(binaryImage, 'holes');
boundaries = bwboundaries(filledImage);
```
```% Collect some of the measurements into individual arrays.
perimeters = [blobMeasurements.Perimeter];
areas = [blobMeasurements.Area];
filledAreas = [blobMeasurements.FilledArea];
solidities = [blobMeasurements.Solidity];
% Calculate circularities:
circularities = perimeters .^2 ./ (4 * pi * filledAreas);
% Print to command window.
fprintf('#, Perimeter,        Area, Filled Area, Solidity, Circularity\n');
for blobNumber = 1 : numberOfObjects
fprintf('%d, %9.3f, %11.3f, %11.3f, %8.3f, %11.3f\n', ...
blobNumber, perimeters(blobNumber), areas(blobNumber), ...
filledAreas(blobNumber), solidities(blobNumber), circularities(blobNumber));
end
```
```% Say what shape they are.
% IMPORTANT NOTE: depending on the aspect ratio of the rectangle or triangle
% their circularity can go from some minimum number up to a huge number.
for blobNumber = 1 : numberOfObjects
% Outline the object so the user can see it.
thisBoundary = boundaries{blobNumber};
subplot(2, 2, 2); % Switch to upper right image.
hold on;
% Display prior boundaries in blue
for k = 1 : blobNumber-1
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'b', 'LineWidth', 3);
end
% Display this bounary in red.
thisBoundary = boundaries{blobNumber};
plot(thisBoundary(:,2), thisBoundary(:,1), 'r', 'LineWidth', 3);
subplot(2, 2, 4); % Switch to lower right image.

% Determine the shape.
if circularities(blobNumber) < 1.2
message = sprintf('The circularity of object #%d is %.3f,\nso the object is a circle',...
blobNumber, circularities(blobNumber));
shape = 'circle';
elseif circularities(blobNumber) < 1.6
message = sprintf('The circularity of object #%d is %.3f,\nso the object is a square',...
blobNumber, circularities(blobNumber));
shape = 'square';
elseif circularities(blobNumber) > 1.6 && circularities(blobNumber) < 1.8
message = sprintf('The circularity of object #%d is %.3f,\nso the object is an isocoles triangle',...
blobNumber, circularities(blobNumber));
shape = 'triangle';
else
message = sprintf('The circularity of object #%d is %.3f,\nso the object is something else.',...
blobNumber, circularities(blobNumber));
shape = 'something else';
end
% Display in overlay above the object
overlayMessage = sprintf('Object #%d = %s\ncirc = %.2f, s = %.2f', ...
blobNumber, shape, circularities(blobNumber), solidities(blobNumber));
text(blobMeasurements(blobNumber).Centroid(1), blobMeasurements(blobNumber).Centroid(2), ...
overlayMessage, 'Color', 'r');
button = questdlg(message, 'Continue', 'Continue', 'Cancel', 'Continue');
if strcmp(button, 'Cancel')
break;
end
end
```

## 7 Comments

Image Analyst on 29 Jul 2012

Think of the convex hull as if you wrapped a rubber band around your object. If an object had no concavities, like a perfect square or circle, then the solidity = 1 because there are no points on the perimeter the rubber band does not touch. Now if the blob looked like a boomerang, then there would be a huge concavity where the rubber band would not touch the perimeter, so it's solidity would be much less than 1.

Tulips on 31 Jul 2012

can I know from the code given, how can I remove the rectangle such as in the photo http://www.flickr.com/photos/80166922@N06/7681815436/in/photostream/ I just want the inverted triangle shape only.many thanks.

Image Analyst on 31 Jul 2012

Detect the rectangle - it will have the smallest area. Then use ismember to remove it. Have you run my BlobsDemo? It goes over all this.

Contact us