几何尺寸与公差论坛

 找回密码
 注册
查看: 1194|回复: 2

求解任意多边形最大内接矩形

  [复制链接]
发表于 2024-1-9 17:29:05 | 显示全部楼层 |阅读模式
https://blog.csdn.net/chenchensuperb/article/details/135273486
1.有一个项目需要求取任意多边形的最大内接矩形,找了halcon中的相关算子只有一个符合类似需求:

inner_rectangle1 — Largest inner rectangle of a region.

The operator inner_rectangle1 determines the largest axis-parallel rectangle that fits into a region. The rectangle is described by the coordinates of the corner pixels (Row1, Column1, Row2, Column2).

使用这个算子只能求得Region内最大的轴平行内接矩形,无法算出任意角度的最大内接矩形。

于是换个角度思考,将Region进行旋转,使用该算子求出剖分角度的ROI内轴平行内接矩形,

然后筛选出最大面积的内接矩形,并将此角度的内接矩形结果进行逆旋转Region的旋转角度,得出最大内接矩形,代码如下:

dev_open_window (0, 0, 800, 700, 'black', WindowHandle)
*dev_update_off ()

*生成一个图片,图片的像素大小求取精度,像素数越多,精度越高,同时运行所花时间越多。
gen_image_const (Image, 'byte', 5120, 3840)

dev_display (Image)

*画一个ROI (画一个闭合的polygon)

draw_polygon (PolygonRegion1, WindowHandle)
fill_up (PolygonRegion1, RegionFillUp)

*//Region旋转起始角度

StartAngle:=-180

*旋转停止角度
StopAngle:=180//Region

*//剖分数
times:=1000

*//剖分角度间距
step:=(rad(StopAngle)-rad(StartAngle))/times

*存储内接矩形面积
AREAS:=[]

*存储角度
Angles:=[]

*存储内接矩形的左上和右下坐标位置
Row1s:=[]
Col1s:=[]
Row2s:=[]
Col2s:=[]

*开始计算

for Index := 1 to times by 1

*获取当前步的角度值
     AngleStep:=(Index-1)*step+rad(StartAngle)

*获取Region的中心
     area_center (RegionFillUp, Area, Row, Column)

*将Region旋转一个步的角度
     vector_angle_to_rigid (Row, Column, 0, Row, Column, AngleStep, HomMat2D)  
     affine_trans_region (RegionFillUp, RegionAffineTrans, HomMat2D, 'nearest_neighbor')

*求取轴平行内接矩形
     inner_rectangle1 (RegionAffineTrans, Row1, Column1, Row2, Column2)   

*存储内接矩形的结果
     Row1s:=[Row1s,Row1]
     Col1s:=[Col1s,Column1]
     Row2s:=[Row2s,Row2]
     Col2s:=[Col2s,Column2]

*获取矩形的面积
     gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
     area_center (Rectangle, Area1, Row3, Column3)

*存储面积和角度
     AREAS:=[AREAS,Area1]
     Angles:=[Angles,AngleStep]


endfor

*对内接矩形的面积进行排序,找到最大的矩形面积和索引值

tuple_sort_index (AREAS, Indices)
tuple_length (Indices, Length)

*获取最大内接矩形的参数和Region旋转的角度

AngleOfMaxArea:=Angles[Indices[Length-1]]
Row1OfMaxRect:=Row1s[Indices[Length-1]]
Col1OfMaxRect:=Col1s[Indices[Length-1]]
Row2OfMaxRect:=Row2s[Indices[Length-1]]
Col2OfMaxRect:=Col2s[Indices[Length-1]]

*将找到的内接矩形反向旋转最大矩形面积索引处Region旋转的角度

area_center (RegionFillUp, Area, Row, Column)
vector_angle_to_rigid (Row, Column, AngleOfMaxArea, Row, Column,0, HomMat2D)
gen_rectangle1 (RectangleMax, Row1OfMaxRect, Col1OfMaxRect, Row2OfMaxRect, Col2OfMaxRect)
affine_trans_region (RectangleMax, RectangleMaxInPos, HomMat2D, 'nearest_neighbor')
dev_clear_window ()
dev_display (Image)
dev_set_color ('red')
dev_display (RegionFillUp)
dev_set_color ('green')
dev_display(RectangleMaxInPos)

*求取矩形的角度和面积相关参数

tuple_deg (AngleOfMaxArea, Deg)
area_center (RectangleMaxInPos, Area2, Row4, Column4)

效果如下:
————————————————
版权声明:本文为CSDN博主「chenchensuperb」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chenchensuperb/article/details/135273486
发表于 2024-11-8 11:28:53 | 显示全部楼层
    // 将 Eigen::Vector2d 类型的点转换为 cv::Point2f 类型
    std::vector<cv::Point2f> pointsCV;
    for (const auto& point : points)
    {
        pointsCV.emplace_back(static_cast<float>(point.x()), static_cast<float>(point.y()));  // 使用 Eigen::Vector2d 的 .x() 和 .y()
    }
    // 使用 minAreaRect 函数拟合旋转矩形(非线性模型)
    cv::RotatedRect rotatedRect = cv::minAreaRect(pointsCV);
发表于 2024-11-8 11:30:05 | 显示全部楼层
minAreaRect缺点:1.不能用double... 2.不能算最大内接,估计是LS这种最小结果
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2024-12-22 02:00 , Processed in 0.037738 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表