Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate objects circumscribed radius and inscribed radius - Matlab

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 enter image description here

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:

  • Object 1: inscribedRadius = 264, cumscribedRadius = 186.6762
  • Object 2: inscribedRadius = 130.4079, circumscribedRadius = 132.3831

The values of object 1 (box) are wrong as the inscribedRadius can not be bigger than the cumscribedRadius. They are fine for object 2 (circle)

like image 879
jane Avatar asked May 22 '20 09:05

jane


1 Answers

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.

like image 138
Cris Luengo Avatar answered Nov 05 '22 03:11

Cris Luengo