detect certain shapes in binary
Mostrar comentarios más antiguos
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!
Respuesta aceptada
Más respuestas (2)
Image Analyst
el 3 de Jul. de 2012
Editada: Image Analyst
el 9 de Jul. de 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
11 comentarios
Tulips
el 16 de Jul. de 2012
Tulips
el 28 de Jul. de 2012
Image Analyst
el 28 de Jul. de 2012
poly2mask takes some x,y coordinates and turns them into an image with the coordinates defining the polygon. Solidity is the fraction that a shape takes up of its convex hull. For triangles, squares, and circles with perfect sides, this should be 1. If the sides were wavy/wiggly then it could be less than 1.
Tulips
el 29 de Jul. de 2012
Image Analyst
el 29 de Jul. de 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
el 31 de Jul. de 2012
Image Analyst
el 31 de Jul. de 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.
nawaf
el 17 de Abr. de 2016
@Image Analyst, Could you please explain your note: "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". What is the best way to tackle this problem?
Image Analyst
el 17 de Abr. de 2016
Editada: Image Analyst
el 17 de Abr. de 2016
As the shape get smaller, the shape is less defined. For example, if the shape is
0 1
1 1
That's a pretty small triangle. What is the area? is it 3? Or is it the square root of 2? What is the perimeter? Is it 3? Or is it 2+sqrt(2)? The circularity for small blocky/quantized shapes like this is affected greatly by the answers to those questions, and to the size of them. In addition, the perimeter might depend on what orientation the shape is at, like 0, 20 degrees, 40 degrees, 75 degrees, or whatever. Just try it and see.
You will find it useful to run my shape recongition demo, attached.
nawaf
el 17 de Abr. de 2016
Thank you! this is very helpful, appreciated!
Laveena Kewlani
el 3 de Ag. de 2016
Image Analyst, Is there any way to know the circularity of other important shape, hexagon, star etc?
murk hassan memon
el 11 de Abr. de 2018
0 votos
Hi Image Analyst, Currently i am working on microscopic blood images in order to detect infected parasites of malaria and for this implementation first i need much data set . i have gone through two different image resources (ASH,CDC) but did not find much data set there. so its my request to you that i you have data set of microscopic blood images(normal,abnormal)then kindly help me out or suggest me another image resources to get from there. waiting for your response
Categorías
Más información sobre Image Processing Toolbox en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
