用opencvSharp实现在任意多边形内找出近似最大的正交内接矩形

通过OpenCVSharp,本文介绍了如何在任意多边形内部找出近似最大的正交内接矩形。首先简化多边形轮廓,然后计算最小外接矩形。通过尝试不同大小的矩形,最终确定最佳尺寸,并采用暴力搜索算法,以矩形左上角为基准,遍历寻找最大面积的内接矩形。
摘要由CSDN通过智能技术生成

用opencvSharp实现在任意多边形内找出近似最大的内接矩形


在网上搜了挺多求任意多边形内最大的内接矩形的文章,但是都不怎么符合我的需求,然后再 这个网站找到了思路,由于里面有些步骤看不太懂,于是就变通了一下,参考里面的方法,用比较简化的方法实现了需求,这个简化的方法优点是容易理解,缺点是可能不怎么精确,但也足够近似,可以用了,先看看结果。
原图:
在这里插入图片描述
结果:
在这里插入图片描述
更准确的结果:
更准确的结果

1.先求出多边形的近似轮廓,减少轮廓数量,方便后面计算:

            var src = Cv2.ImRead("C:\\Users\\Administrator\\Desktop\\test.png", ImreadModes.Grayscale);
            Cv2.FindContours(src, out var contours, out var hierarchy, RetrievalModes.External, 
                ContourApproximationModes.ApproxSimple);
            List<Point[]> approxContours = new List<Point[]>();
            for (int i = 0; i < contours.Length; i++)
            {
   
                //先求出多边形的近似轮廓,减少轮廓数量,方便后面计算
                var approxContour = Cv2.ApproxPolyDP(contours[i], 15, true);
                approxContours.Add(approxContour);
                DrawContour(src, approxContour, Scalar.White, 3);
            }

多边形的最小外接多边形
2.根据上面的近似轮廓绑定最小外接矩形
在这里插入图片描述

3.在多边形最小外接矩形里画满给定宽高的矩形,但只有在轮廓内的矩形才会画出来,可以看出还有一些空位没有填满,但如果画的矩形再小一点,精度会更高
给定宽高35X35像素的矩形
在这里插入图片描述
给定宽高20X20像素的矩形
在这里插入图片描述

4. 遍历所有在轮廓内部的矩形索引,以该矩形左上角的点为标准,先往右找出最大的宽,再往下找出最大的高,构建一个假定的大矩形,再遍历假定大矩形内的每一个小矩形,两两再次组合成一个矩形,不断比较,算出最大面积。
步骤就是这些,思路比较简单暴力,花费时间也还可以接受,完整代码如下:

        public Form1()
        {
   
            InitializeComponent();
            var src = Cv2.ImRead("C:\\Users\\Administrator\\Desktop\\test.png", ImreadModes.Grayscale);
            Cv2.FindContours(src, out var contours, out var hierarchy, RetrievalModes.External, 
                ContourApproximationModes.ApproxSimple);
            List<Point[]> approxContours = new List<Point[]>();
            for</
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用OpenCV中的minAreaRect函数来寻找最小外接矩形,然后通过旋转矩阵将其旋转到水平方向。接下来,我们需要找到该矩形多边形内的最大内接正交矩形。 具体实现步骤如下: 1. 找到多边形的边界框,即使用boundingRect函数可以找到。 2. 将最小外接矩形旋转到水平方向,可以使用getRotationMatrix2D函数和warpAffine函数实现。 3. 将多边形的所有点旋转相同的角度以保持一致性。 4. 对边界框中的每个像素,找到其在旋转后的坐标系中的位置,并计算其离矩形边界的距离。 5. 找到距离最小的像素,并计算其周围的像素是否都在矩形内部。 6. 如果是,则将该像素作为最大内接正交矩形的左上角点。 7. 以该点为起点,向右和向下分别寻找最大矩形边界,即为最大内接正交矩形。 下面是示例代码: ```python import cv2 import numpy as np def find_max_inner_rect(poly): # 找到多边形的边界框 x,y,w,h = cv2.boundingRect(poly) rect = ((x,y),(w,h),0) # 将最小外接矩形旋转到水平方向 box = cv2.boxPoints(rect) center = rect[0] angle = rect[2] M = cv2.getRotationMatrix2D(center, angle, 1.0) box = np.int0(cv2.transform(np.array([box]), M))[0] rect = cv2.minAreaRect(box) # 将多边形的所有点旋转相同的角度 poly = np.int0(cv2.transform(np.array([poly]), M))[0] # 找到矩形内的最大正交矩形 max_rect = None max_area = 0 for i in range(x, x+w): for j in range(y, y+h): # 计算像素在旋转后的坐标系中的位置 r = np.array([[i],[j],[1]]) r = np.matmul(np.linalg.inv(M), r) # 计算像素到矩形边界的距离 dist = cv2.pointPolygonTest(poly, (r[0][0], r[1][0]), True) # 如果像素在矩形内部,则寻找最大矩形边界 if dist >= 0: rect = ((i,j),(1,1),0) x1,y1,w1,h1 = cv2.boundingRect(np.array([rect])) if w1*h1 > max_area and cv2.pointPolygonTest(poly, (x1+w1-1, y1+h1-1), False) >= 0: max_rect = (x1,y1,w1,h1) max_area = w1*h1 return max_rect ``` 其中,poly为多边形的顶点坐标,返回的max_rect为最大内接正交矩形的左上角点、宽度和高度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值