Cannot obtain all centroids from loop and shape detection
이전 댓글 표시
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
답변 (1개)
Image Analyst
2022년 11월 25일
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
Chanoknunt Sangsobhon
2022년 11월 28일
Image Analyst
2022년 11월 28일
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
2022년 11월 29일
Image Analyst
2022년 11월 29일
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
2022년 11월 30일
편집: Chanoknunt Sangsobhon
2022년 11월 30일
Image Analyst
2022년 11월 30일
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
2022년 12월 1일
카테고리
도움말 센터 및 File Exchange에서 Image Arithmetic에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!