Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Width and height of a rotated polyshape object - Matlab

Tags:

matlab

Based on this question I am trying to calculate the width and height of an object. I did so by converting the examined object to a polyshape and rotated. How can I extract the width and height of the rotated polyshape object? Is there a way to do it using regionprop and will it be more efficient?

Code:

clc;
clear;
close all;

Image = rgb2gray(imread('pillsetc.png'));
BW = imbinarize(Image);
BW = imfill(BW,'holes');
BW = bwareaopen(BW, 100);
[B,L] = bwboundaries(BW,'noholes');

imshow(Image);
hold on;

k=3;
stat = regionprops(BW,'Centroid','Orientation','MajorAxisLength');
b = B{k};
yBoundary = b(:,2);
xBoundary = b(:,1);
centroidObject = stat(k).Centroid;
xCentre = centroidObject(:,2);
yCentre = centroidObject(:,1);
plot(yCentre, xCentre, 'r*')

orientationDegree =  stat(k).Orientation
hlen = stat(k).MajorAxisLength/2;
cosOrient = cosd(stat(k).Orientation);
sinOrient = sind(stat(k).Orientation);
xcoords = xCentre + hlen * [cosOrient -cosOrient];
ycoords = yCentre + hlen * [-sinOrient sinOrient];

plot(yBoundary, xBoundary, 'r', 'linewidth', 3);
pgon = polyshape(yBoundary, xBoundary);  
polyRot = rotate(pgon,(90+orientationDegree),centroidObject);  
plot(polyRot);  

[xlim,ylim] = boundingbox(polyRot);
Height = xlim(2) - xlim(1); 
Width = ylim(2) - ylim(1);
like image 347
wrek Avatar asked Nov 18 '25 09:11

wrek


1 Answers

I would use the angle returned by the minimum Feret diameter calculation to rotate the polygon. Usually, the box at this rotation is the box with minimal area (exceptions seem to be very rare). The 'Orientation' feature is computed based on the best fit ellipse, and would not necessarily yield a small box.

Instead of rotating the full object polygon, you can also rotate only the convex hull, which typically contains fewer points and thus would be more efficient. The Feret computation already uses the convex hull, so there is no additional cost to requesting it from regionprops.

This is code that does what I describe:

Image = rgb2gray(imread('pillsetc.png'));
BW = imbinarize(Image);
BW = imfill(BW,'holes');
BW = bwareaopen(BW, 100);

stat = regionprops(BW,'ConvexHull','MinFeretProperties');

% Compute Feret diameter perpendicular to the minimum diameter
for ii=1:numel(stat)
    phi = stat(ii).MinFeretAngle; % in degrees
    p = stat(ii).ConvexHull * [cosd(phi),-sind(phi); sind(phi),cosd(phi)];
    minRect = max(p) - min(p); % this is the size (width and height) of the minimal bounding box
    stat(ii).MinPerpFeretDiameter = minRect(2); % add height to the measurement structure
end

Note that the first value of minRect in the code above is the width of the object (smallest side of minimum bounding box), and equivalent to stat(ii).MinFeretDiameter. The two values are not identical because they are computed differently, but they are pretty close. The second value of minRect, which is saved as “MinPerpFeretDiameter”, is the height (or rather the longest side of the minimum bounding box).

like image 162
Cris Luengo Avatar answered Nov 21 '25 10:11

Cris Luengo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!