I am trying to calculate two objects circumscribed radius and inscribed radius using the code below. I used for the inscribedRadius parameter from this script and for the circumscribed radius I used this function
I do not understand why I get for the box shape that the inscribed radius is bigger than the circumscribed radius. Any idea what is wrong? And how to fix it?
Image
Code:
clc;
clear;
RGB = imcomplement(imread('https://i.stack.imgur.com/8WLAt.jpg'));
I = rgb2gray(RGB);
bw = imbinarize(I);
bw = imfill(bw,'holes');
imshow(bw)
hold on;
[B,L] = bwboundaries(bw,'noholes');
stats = regionprops(L,'Centroid','MajorAxisLength');
for i = 1 : numel(stats)
b = B{i};
c = stats(i).Centroid;
y = b(:,1);
x = b(:,2);
plot( b(:,2),b(:,1),'Color','red','linewidth',2);
text(c(1),c(2),num2str(i),'Color','red');
xMin = min(x);
xMax = max(x);
yMin = min(y);
yMax = max(y);
scalingFactor = 1000 / min([xMax-xMin, yMax-yMin]);
x2s = (x - xMin) * scalingFactor + 1;
y2s = (y - yMin) * scalingFactor + 1;
mask = poly2mask(x2s, y2s, ceil(max(y2s)), ceil(max(x2s)));
edtImage = bwdist(~mask);
inscribedRadius = max(edtImage(:));
[yCenter, xCenter] = find(edtImage == inscribedRadius);
xCenter = (xCenter - 1)/ scalingFactor + xMin;
yCenter = (yCenter - 1)/ scalingFactor + yMin;
inscribedRadius = inscribedRadius / scalingFactor
[circumscribedCenter,circumscribedRadius] = minboundcircle(x,y); % from https://www.mathworks.com/matlabcentral/fileexchange/34767-a-suite-of-minimal-bounding-objects?focused=3820656&tab=function
circumscribedRadius
end
The results are:
inscribedRadius
= 264, cumscribedRadius
= 186.6762inscribedRadius
= 130.4079, circumscribedRadius
= 132.3831The values of object 1 (box) are wrong as the inscribedRadius
can not be bigger than the cumscribedRadius
. They are fine for object 2 (circle)
If you look at the mask
image, you'll notice that the square shape is drawn touching the right and bottom edges of the image. There's background only along the left and top of the shape. The distance transform bwdist(~mask)
subsequently computes the distance to the background for each pixel within the shape, but since there's background only to the left and top, the pixel at the bottom right of the shape has a distance of 1000, rather than 1. The distance transform is supposed to have a maximum in the middle, at a point equidistant to at least the three nearest shape edge points.
The solution is simple: poly2mask
must create an image that is one pixel wider and taller:
mask = poly2mask(x2s, y2s, ceil(max(y2s)) + 1, ceil(max(x2s)) + 1);
^^^ ^^^
With this change, the computed inscribedRadius
for the square is 132, as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With