Cannot obtain all centroids from loop and shape detection
Show older comments
Hello. I have some problem extracting centroid from loop.
I have code for detecting some shape in images in folder.
I have 2 problems from this code.
First, I have to extract centroids from the loop, the problem is the matrix store centroid for only 1 image, when it run the next image, the new centroid was overwritten over the centroid from previous image.
Second, for detecting shape in image, the bounding box and extent were used (I modified some code from Shape Recognition to detect ellipse). The problem is both not-perfect rectangle and not-perfect circle were detected as and ellipse but I don't want it to detect rectangle.
Could anyone help me about these please? This is the code I used. Thank you in advanced!
%Specify the folder where the files live.
myFolder = 'C:\Users\---';
filePattern = fullfile(myFolder, '*.jpg');
theFiles = dir(filePattern);
for k = 1 : length(theFiles)
baseFileName = theFiles(k).name;
fullFileName = fullfile(theFiles(k).folder,baseFileName);
originalImage = imread(fullFileName);
ROI = roipoly(originalImage,x,y); %apply ROI
imshow(ROI);
[rows, columns, numberOfColorChannels] = size(originalImage);
mask = poly2mask(x, y, rows, columns);
maskedRgbImage = originalImage .* cast(mask, 'like', originalImage); %Masking outside ROI
GRAY = rgb2gray(maskedRgbImage); %Grey scaling the image
%Binarizing image using edge detection
BW = edge(GRAY,'canny',0.4);
[B,L] = bwboundaries(BW, 'noholes');
STATS = regionprops(L, 'all'); % we need 'BoundingBox' and 'Extent'
hold on
%Detecting shape
figure,
imshow(originalImage),
hold on
T = [];
filename3 = [sprintf('%01d',k) '.jpg'];
fullname3 = fullfile(currentFolder,'Object detected images',filename3);
for i = 1 : length(STATS)
W(i) = uint8(abs(STATS(i).BoundingBox(3)-STATS(i).BoundingBox(4)) < 0.1); %If width and height of bounding box are equal(circle,square), W(i)=1, otherwise W(i)=0
W(i) = W(i) + 2 * uint8((STATS(i).Extent - 1) == 0 ); % Extent =1; If circle/ellipse, back term=0, rec/sqr back term =2
W(i) = W(i) + 4 * uint8((STATS(i).Extent - 1) <= 0.7854); %Extent = pi/4 case ellipse/circle
centroid = STATS(i).Centroid;
switch W(i)
case 5 %circle
plot(centroid(1),centroid(2),'wO');
x_centroid = centroid(1:2:end);
y_centroid = centroid(2:2:end);
T = [T; x_centroid y_centroid];
ax = gca;
exportgraphics(ax,fullname3)
case 2 %rectangle
plot(centroid(1),centroid(2),'wX');
x_centroid = centroid(1:2:end);
y_centroid = centroid(2:2:end);
T = [T; x_centroid y_centroid];
ax = gca;
exportgraphics(ax,fullname3)
case 3 %square
plot(centroid(1),centroid(2),'wS');
x_centroid = centroid(1:2:end);
y_centroid = centroid(2:2:end);
T = [T; x_centroid y_centroid];
ax = gca;
exportgraphics(ax,fullname3)
case 4 %ellipse
plot(centroid(1),centroid(2),'w+');
x_centroid = centroid(1:2:end);
y_centroid = centroid(2:2:end);
T = [T; x_centroid y_centroid]
ax =gca;
exportgraphics(ax,fullname3)
end
end
close
end
Answers (1)
Image Analyst
on 25 Nov 2022
You can store all centroids right after you call regionprops, if you want
STATS = regionprops(L, 'all'); % we need 'BoundingBox' and 'Extent'
allCentroidsXY = vertcat(STATS.Centroid)
7 Comments
Chanoknunt Sangsobhon
on 28 Nov 2022
Image Analyst
on 28 Nov 2022
I have no idea how you want to specify the ones you want to keep or exclude. Explain it to me.
If you have any more questions, then attach your image with the paperclip icon after you read this:
Chanoknunt Sangsobhon
on 29 Nov 2022
Image Analyst
on 29 Nov 2022
I don't know what that code is for. Basically you need to binarize the image for where it's not white. Then find bounding boxes and extents and then do the switch to examine them to see what kind of shape it is. Then put up the appropriate title and centroid marker. Something like (untested)
[r, g, b] = imsplit(rgbImage);
whiteMask = (r == 255) & (g == 255) & (b == 255);
shapeMask = imclearborder(~whiteMask);
props = regionprops(shapeMask, 'Centroid', 'BoundingBox');
allCentroidsCY = vertcat(props.Centroid)
allExtents = [props.Extent]
allBB = vertcat(props.BoundingBox
for k = 1 : numel(props)
aspectRatio = allBB(k, 3) / allBB(k, 4);
if abs(1 - aspectRatio) < 0.05
% It's a square or circle
else
% It's a rectangle or oval
end
end
I trust you know how to put in the check for extents to check for square vs circle, and for rectangle vs oval, and how to put up the right marker in the right location. If you can't figure it out, let me know.
Chanoknunt Sangsobhon
on 30 Nov 2022
Edited: Chanoknunt Sangsobhon
on 30 Nov 2022
Image Analyst
on 30 Nov 2022
Those are JPG artifacts. That is why you should never use JPG images for image analysis if you can avoid it. So change your mask to
whiteMask = (r > 240) & (g > 240) & (b > 240);
Chanoknunt Sangsobhon
on 1 Dec 2022
Categories
Find more on Image Segmentation 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!