Я бы использовал угол, возвращенный вычислением минимального диаметра Ферета, чтобы вращать многоугольник. Обычно при этом повороте поле представляет собой поле с минимальной площадью (исключения кажутся очень редкими). Функция «Ориентация» рассчитывается на основе эллипса наилучшего соответствия и не обязательно приведет к появлению небольшого прямоугольника.
Вместо поворота многоугольника всего объекта вы также можете вращать только выпуклый корпус, который обычно содержит меньше очки и, следовательно, будет более эффективным. В вычислениях Ферета уже используется выпуклая оболочка, поэтому при запросе этого у regionprops
.
нет никаких дополнительных затрат. Это код, который выполняет то, что я описываю:
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
Обратите внимание, что первое значение minRect
в приведенном выше коде является шириной объекта и эквивалентно stat(ii).MinFeretDiameter
. Два значения не идентичны, потому что они вычисляются по-разному, но они довольно близки. Второе значение minRect
, которое сохраняется как «MinPerpFeretDiameter», является высотой.