How to detect and separate squares and circles on image ?

45 ビュー (過去 30 日間)
Amar Mesic
Amar Mesic 2022 年 1 月 18 日
編集済み: Adam Danz 2022 年 1 月 18 日
Hi guys.As a total beginner in Matlab i couldn't find a way to do this task myself, so my last hope is someone here.I need to detect squares in one image,then separate them(hide everything else in picture)and count them.Same with circles. The picture is shown below.

採用された回答

Adam Danz
Adam Danz 2022 年 1 月 18 日
編集済み: Adam Danz 2022 年 1 月 18 日
This should get you started. It uses regionprops to compute the circularity of each object. I've set a subjective threshold of 0.9 where circularity values >0.9 are defined as circles and <=0.9 are not circles. See inline comments for details. Requires Matlab R2019a or later.
% Read image file, convert to binary
file = 'image.png'; % full path is usually better
RGB = imread(file);
mask = imbinarize(rgb2gray(RGB));
% Detect shapes, compute circularity (Assumption: Shapes do not overlap)
stats = regionprops(~mask,{'Circularity','SubarrayIdx'});
circleThreshold = 0.9; % circularity values greater than this are cirlces
% Copy the colored image twice; eliminate circles and squares
RGBcircles = RGB;
RGBsquares = RGB;
for i = 1:numel(stats)
circularity = stats(i).Circularity;
if circularity <= circleThreshold
% remove object if it's not a circle
RGBcircles(stats(i).SubarrayIdx{1}, stats(i).SubarrayIdx{2},:) = uint8(255);
elseif circularity > circleThreshold
% remove object if it's a circle
RGBsquares(stats(i).SubarrayIdx{1}, stats(i).SubarrayIdx{2},:) = uint8(255);
end
end
% Count objects
nCircles = sum([stats.Circularity] > circleThreshold);
nSquares = sum([stats.Circularity] <= circleThreshold);
% Show results
figure
tiledlayout(2,2,'TileSpacing','compact','Padding','compact')
nexttile([1,2])
imshow(RGB)
title(sprintf('Original: %d objects', numel(stats)))
axis on
nexttile
imshow(RGBcircles)
title(sprintf('%d circles', nCircles))
axis on
nexttile
imshow(RGBsquares)
title(sprintf('%d squares', nSquares))
axis on
  7 件のコメント
Image Analyst
Image Analyst 2022 年 1 月 18 日
You can use area and perimeter to get circularities:
stats = regionprops(~mask, 'Area', 'Perimeter', 'SubarrayIdx');
allAreas = [stats.Area];
allPerimeters = [stats.Perimeter];
stats.circularities = (4 * pi * allAreas) ./ allPerimeters .^2;
Adam Danz
Adam Danz 2022 年 1 月 18 日
Thanks, @Image Analyst!

サインインしてコメントする。

その他の回答 (1 件)

Image Analyst
Image Analyst 2022 年 1 月 18 日
See my attached shape recognition demos. Circularity is one way. Also getting distance from centroid and counting peaks is another way. Most ways will breakdown as the shapes get smaller and more pixellated/quantized. And just because a shape has a certain number of vertices does not indicate a certain shape. For example a pentagon and star both have 5 outward vertices.

カテゴリ

Help Center および File ExchangeImage Data Workflows についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by