You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab中如何获取旋转多边形对象的真实最大宽高(非边界框)

在Matlab中获取旋转polyshape对象的真实最大宽高

你现在的代码计算的是最小包围盒的宽高,但你要的是对象自身的「真实最大宽高」——也就是沿着某个方向上,对象上任意两点的最大跨度(类似椭圆的长轴/短轴长度),这和包围盒尺寸确实不是一回事。下面给你两种可行的实现方案:

方案一:遍历所有角度计算投影跨度(精度可控)

这个方法通过遍历不同角度,计算对象凸包在该角度下的投影跨度,找到最大的那个值,精度可以通过角度步长调整:

clc; clear all; 
Image = imread('E:/moon.gif'); 
BW = imbinarize(Image); 
BW = imfill(BW,'holes'); 
BW = bwareaopen(BW, 100); 
stat = regionprops(BW,'ConvexHull'); 

% 初始化最大宽高变量
max_width = 0;
max_height = 0;
best_angle_w = 0;
best_angle_h = 0;

% 遍历0-180度的角度(步长0.5度,步长越小精度越高)
angles = 0:0.5:180;

for ii=1:numel(stat)
    hull_points = stat(ii).ConvexHull; % 用凸包点计算,和原对象最大跨度一致,且计算更快
    
    for phi = angles
        % 构建旋转矩阵,将点旋转到以phi为x轴的坐标系
        rot_mat = [cosd(phi), sind(phi); -sind(phi), cosd(phi)];
        rotated_points = hull_points * rot_mat;
        
        % 计算当前角度下的x方向跨度(宽度)和y方向跨度(高度)
        curr_w = max(rotated_points(:,1)) - min(rotated_points(:,1));
        curr_h = max(rotated_points(:,2)) - min(rotated_points(:,2));
        
        % 更新最大宽高记录
        if curr_w > max_width
            max_width = curr_w;
            best_angle_w = phi;
        end
        if curr_h > max_height
            max_height = curr_h;
            best_angle_h = phi;
        end
    end
end

% 输出结果
fprintf('真实最大宽度: %.2f (对应角度: %.1f°)\n', max_width, best_angle_w);
fprintf('真实最大高度: %.2f (对应角度: %.1f°)\n', max_height, best_angle_h);

关键说明:

  • 用凸包点而不是原对象所有点:凸包包含了对象的所有极端点,计算凸包的跨度和原对象完全一致,但点的数量更少,能大幅提升计算速度。
  • 角度遍历范围:只需要遍历0-180度,因为180度和0度的方向是完全重复的。
  • 步长调整:如果需要更高精度,可以把步长改成0.1度,但计算时间会相应增加。

方案二:直接用Regionprops的Feret属性(简单快捷)

如果你的Matlab版本支持,regionprops的FeretProperties可以直接返回对象的最大Feret直径(也就是你要的真实最大跨度),以及对应的角度:

clc; clear all; 
Image = imread('E:/moon.gif'); 
BW = imbinarize(Image); 
BW = imfill(BW,'holes'); 
BW = bwareaopen(BW, 100); 
stat = regionprops(BW,'FeretProperties','ConvexHull');

% 最大Feret直径就是真实最大宽度/高度(取最大的那个)
max_span = stat.FeretDiameter;
max_span_angle = stat.FeretAngle;

% 如果需要垂直于最大跨度方向的高度,直接计算90度方向的跨度
perp_phi = max_span_angle + 90;
rot_mat = [cosd(perp_phi), sind(perp_phi); -sind(perp_phi), cosd(perp_phi)];
rotated_points = stat.ConvexHull * rot_mat;
perp_span = max(rotated_points(:,1)) - min(rotated_points(:,1));

fprintf('真实最大跨度: %.2f (对应角度: %.1f°)\n', max_span, max_span_angle);
fprintf('垂直方向最大跨度: %.2f (对应角度: %.1f°)\n', perp_span, perp_phi);

关键说明:

  • Feret直径的定义就是对象上任意两点在某个方向上的投影距离的最大值,完全符合你说的「真实最大宽高」。
  • 如果你需要的是一对垂直的宽高(类似长轴短轴),可以在得到最大跨度的角度后,直接计算其垂直方向的跨度即可。

内容的提问来源于stack exchange,提问作者hs100

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 18:27:37