精华内容
下载资源
问答
  • 一个矩形的最小外接矩形
    千次阅读
    2022-07-07 20:54:27

            经常需要用到opencv二值化、轮廓线检测、求外接矩形、最小外接矩形、矩形的四个点坐标等等,并显示。这里整理下:

    1、函数说明

    1.1、cv2.threshold()

            阈值的作用是根据设定的值处理图像的灰度值,比如灰度大于某个数值像素点保留。通过阈值以及有关算法可以实现从图像中抓取特定的图形,比如去除背景等。cv2中的阈值相关函数有:普通阈值函数threshold,自适应阈值函数adaptivthreshold。

            函数定义:retval, dst = cv2.threshold(src, thresh, maxval, type[, dst]),其中:src是灰度图像,thresh是起始阈值,maxval是最大值,type是定义如何处理数据与阈值的关系。有以下几种:

    选项 像素值>thresh 其他情况:

            cv2.THRESH_BINARY maxval 0

            cv2.THRESH_BINARY_INV 0 maxval

            cv2.THRESH_TRUNC thresh 当前灰度值

            cv2.THRESH_TOZERO 当前灰度值 0

            cv2.THRESH_TOZERO_INV 0 当前灰度值

    另外的取值为:

            cv2.THRESH_OTSU

            cv2.THRESH_TRIANGLE

            cv2.THRESH_MASK

            cv2.THRESH_OTSU使用最小二乘法处理像素点,而cv2.THRESH_TRIANGLE使用三角算法处理像素点。一般情况下,cv2.THRESH_OTSU适合双峰图。cv2.THRESH_TRIANGLE适合单峰图。

            cv2.THRESH_OTSU、cv2.THRESH_TRIANGLE是标志位,他们可以和其他参数,比如cv2.THRESH_BINARY一起使用。

            当使用cv2.THRESH_OTSU或cv2.THRESH_TRIANGLE时,阈值是动态的,会根据计算结果返回相应的数值。

    1.2、cv2.findContours

            功能:cv2.findContours()函数来查找检测物体的轮廓。

            参数:

            参数1:寻找轮廓的图像,接收的参数为二值图,即黑白的(不是灰度图),所以读取的图像要先转成灰度的,再转成二值图

            参数2: 轮廓的检索模式,有四种。

            cv2.RETR_EXTERNAL 表示只检测外轮廓;

            cv2.RETR_LIST 检测的轮廓不建立等级关系;

            cv2.RETR_CCOMP 建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。

            cv2.RETR_TREE 建立一个等级树结构的轮廓。

            参数3: 轮廓的近似办法.

            cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1

            cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息

            cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使用teh-Chinl chain 近似算法

            注:opencv2返回两个值:contours:hierarchy。opencv3会返回三个值,分别是img, countours, hierarchy

    返回值:

            cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。

    1.3、其它

            cv2.threshold() —— 阈值处理

            cv2.findContours() —— 轮廓检测

            cv2.boundingRect() —— 最大外接矩阵

            cv2.rectangle() —— 画出矩形

            cv2.minAreaRect —— 找到最小外接矩形(矩形具有一定的角度)

            cv2.boxPoints —— 外接矩形的坐标位置

            cv2.drawContours(image, [box], 0, (0, 0, 255), 3) —— 根据点画出矩形

    2、测试代码

    # -*- coding: utf-8 -*-
    
    
    import cv2
    import numpy as np
    
    image = cv2.imread('test.jpg')
    # 图像转灰度图
    img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 图像转二值图
    ret, thresh = cv2.threshold(img, 230, 255, cv2.THRESH_BINARY_INV)
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
     # 轮廓线提取矩形、最小外接矩形、四个点
    for c in contours:
        if len(c) < 10: # 去除外轮廓
            continue
        
        # 找到边界坐标
        x, y, w, h = cv2.boundingRect(c)  # 计算点集最外面的矩形边界
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) # 红
    
        # 找面积最小的矩形
        rect = cv2.minAreaRect(c) #((cx, cy), (bw, bh), angle), 浮点数
        # 得到最小矩形的坐标
        box = cv2.boxPoints(rect)# 最小外接矩形的四个点坐标,浮点数
        # 标准化坐标到整数
        box = np.int0(box) #四个点坐标转为整数
        # 画出边界
        cv2.drawContours(image, [box], 0, (0, 255, 0), 3)# 以轮廓线形式画出最小外接矩形,绿色
    
        # 计算最小封闭圆的中心和半径
        (x, y), radius = cv2.minEnclosingCircle(c)
        # 换成整数integer
        center = (int(x), int(y))
        radius = int(radius)
        # 画圆
        cv2.circle(image, center, radius, (255, 0, 0), 2) # 蓝色
    
    cv2.drawContours(image, contours, -1, (100, 100, 100), 1)
    cv2.imshow("img", image)
    cv2.waitKey(0)

            结果:

    更多相关内容
  • 主要为大家详细介绍了Opencv绘制最小外接矩形、最小外接圆的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 最小外接矩形

    2018-05-09 09:39:35
    利用opencv找图像中形状的最小外接矩形,进而可获得最小外接矩形的信息等
  • 最小外接矩形

    2018-01-27 21:55:47
    凸包 蛮力 最小面积 最小外接矩形 文件选择 随机生成 凸包点位 然后求解
  • 通过目标的对角点,可以框出目标的最小外接矩形
  • 资源中包含了两m文件。...minboundrect.m用于绘制运动目标的最小外接矩形框,可任意设置最小外接矩形框的角度。 本人做的是视频中运动车辆的检测,读者可自行更换检测算法以及参数调整以匹配不同的运动场景。
  • 在图像裁剪操作中,opencv和pillow两库都具有相应的函数,但是这两库中的函数仅仅能对与图片平行的矩形进行裁剪操作,如果想要对目标的最小外接矩形进行裁剪该如何操作呢?如下所示: 具体处理该问题的思路如下...
  • 最小外接矩形,计算偏转角,旋转至水平,根据最小的旋转角进行旋转,顺时针或者逆时针
  • 多边形最小外接矩形算法 程鹏飞 题目 给出求一个多边形最小外接矩形的算法并证明求得的是最小外接矩形. 最小外接矩形英文简称为SMBR(smallest minimum bounding rectangle,它和MBR(minimum bounding rectangle)不...
  • 包含多区域的最小外接矩形''' image = cv2.imread('./label.png') B, G, R = cv2.split(image) ret, thresh = cv2.threshold(G, 128, 255, cv2.THRESH_BINARY) print(thresh.shape) # 单通道复制为三通道 ...代替...
  • 主要为大家详细介绍了OpenCV实现最小外接矩形,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要介绍了python opencv minAreaRect 生成最小外接矩形的方法,小编觉得挺不错的,现在分享给大家,也给大家做参考。一起跟随小编过来看看吧
  • 主要为大家详细介绍了Opencv实现最小外接矩形和圆,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 该代码可用于求取一个多边形的最小外接矩形
  • 最小外接矩形求解MBR

    2020-04-06 10:57:35
    参考网页上的历程,完善了软件功能,实现了最小外接矩形求解。在QT上测试通过,输入随意的不等数量的点,运行算法,获取最小矩形的边的所有参数。
  • 最小外接矩形定位器件.rar,最小外接矩形定位器件,.vs,最小外接矩形,v14,.suo,最小外接矩形,最小外接矩形.vcxproj.filters,最小外接矩形.vcxproj,3.jpg,x64,Debug,vc140.pdb,vc140.idb,源.obj,最小外接矩形.tlog,CL....
  • 最小外接矩形matlab

    2015-12-21 19:31:17
    minboundrect: Compute the minimal bounding rectangle of points in the plane % usage: [rectx,recty,area,perimeter] = minboundrect(x,y,metric)
  • matlab 求最小外接矩形

    2014-06-13 13:28:42
    求多目标的最小外接矩形,有说明,matlab版
  • 我就废话不多说了,大家还是直接看代码吧! print("thresh =",thresh) coords = np.column_stack(np.where(thresh ...box = cv2.boxPoints(min_rect)//获取最小矩形的4顶点坐标。 但是通过一下这绘制矩形函数,画
  • 最大最小外接矩形

    import cv2
    import numpy as np
    
    img = cv2.imread('./hello.png')
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    #二值化,注意有两个返回值,阈值和结果
    thresh, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
    contours, hierachy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    rect = cv2.minAreaRect(contours[1])
    #cv2.drawContours(img, contours, 1, (0, 0, 255), 2)这一步可以画轮廓
    #rect是一个Rotated Rect旋转的矩形,矩形的起始坐标xy,长宽,旋转角度
    #注意box给的是小数,但坐标必须是整数,要转化一下
    box = cv2.boxPoints(rect)
    
    box = np.round(box).astype('int64')
    cv2.drawContours(img, [newbox], 0, (0, 0, 255), 2)
    
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

     

    #最大
    import cv2
    import numpy as np
    
    img = cv2.imread('./hello.png')
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    #二值化,注意有两个返回值,阈值和结果
    thresh, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
    contours, hierachy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    rect = cv2.minAreaRect(contours[1])
    #cv2.drawContours(img, contours, 1, (0, 0, 255), 2)这一步可以画轮廓
    #rect是一个Rotated Rect旋转的矩形,矩形的起始坐标xy,长宽,旋转角度
    #注意box给的是小数,但坐标必须是整数,要转化一下
    box = cv2.boxPoints(rect)
    
    box = np.round(box).astype('int64')
    cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
    
    #最大返回四个(xy((wh),此处操作为最大
    x, y, w, h = cv2.boundingRect(contours[1])
    
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

     

    展开全文
  • python 最小外接矩形笔记

    千次阅读 2022-05-16 21:00:34
    生成最小外接矩形: cnt = np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]]) # ...box = cv2.cv.BoxPoints(rect) # cv2.boxPoints(rect) for OpenCV 3.x 获取最小外接矩形的4顶点 box = np.int0(box) RotatedRe..

    目录

    opencv生成最小外接矩形:

    最小外接矩形修正版:


    opencv生成最小外接矩形:

    cnt = np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]]) # 必须是array数组的形式
    
    rect = cv2.minAreaRect(cnt) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
    box = cv2.cv.BoxPoints(rect) # cv2.boxPoints(rect) for OpenCV 3.x 获取最小外接矩形的4个顶点
    box = np.int0(box)
    
    

    RotatedRect该类表示平面上的旋转矩形,有三个属性:

    1. 矩形中心点(质心)
    2. 边长(长和宽)
    3. 旋转角度

    旋转角度angle的范围为[-90,0),当矩形水平或竖直时均返回-90,请看下图:

    一、组成angel的最小外接矩形的边的选取问题。

    angel的形成与选取的最小外接矩形的边有关,在这里我们只给出最终结论,有兴趣的同志,可以自己去验证一下,距离坐标原点最近的最小外接矩形的边,作为angel的一条边或者其延长线,而另一条边为X轴,两条线最终形成一个夹角。如图所示


    ————————————————
    版权声明:本文为CSDN博主「W`Peak」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_39430765/article/details/99431709

    最小外接矩形修正版:

    GitHub - root12321/Rotation-Detect-yolov5_poly

    def cvminAreaRect2longsideformat(x_c, y_c, width, height, theta):
        '''
        trans minAreaRect(x_c, y_c, width, height, θ) to longside format(x_c, y_c, longside, shortside, θ)
        两者区别为:
                当opencv表示法中width为最长边时(包括正方形的情况),则两种表示方法一致
                当opencv表示法中width不为最长边 ,则最长边表示法的角度要在opencv的Θ基础上-90度
        @param x_c: center_x
        @param y_c: center_y
        @param width: x轴逆时针旋转碰到的第一条边
        @param height: 与width不同的边
        @param theta: x轴逆时针旋转与width的夹角,由于原点位于图像的左上角,逆时针旋转角度为负 [-90, 0)
        @return:
                x_c: center_x
                y_c: center_y
                longside: 最长边
                shortside: 最短边
                theta_longside: 最长边和x轴逆时针旋转的夹角,逆时针方向角度为负 [-180, 0)
        '''
        '''
        意外情况:(此时要将它们恢复符合规则的opencv形式:wh交换,Θ置为-90)
        竖直box:box_width < box_height  θ=0
        水平box:box_width > box_height  θ=0
        '''
        # print("theta",theta)
        theta=int(theta)
        if theta == 0:
            theta = -90
            buffer_width = width
            width = height
            height = buffer_width
    
        if theta > 0:
            if theta != 90:  # Θ=90说明wh中有为0的元素,即gt信息不完整,无需提示异常,直接删除
                print('θ计算出现异常,当前数据为:%.16f, %.16f, %.16f, %.16f, %.1f;超出opencv表示法的范围:[-90,0)' % (
                x_c, y_c, width, height, theta))
            return False
    
        if theta < -90:
            print(
                'θ计算出现异常,当前数据为:%.16f, %.16f, %.16f, %.16f, %.1f;超出opencv表示法的范围:[-90,0)' % (x_c, y_c, width, height, theta))
            return False
    
        if width != max(width, height):  # 若width不是最长边
            longside = height
            shortside = width
            theta_longside = theta - 90
        else:  # 若width是最长边(包括正方形的情况)
            longside = width
            shortside = height
            theta_longside = theta
    
        if longside < shortside:
            print('旋转框转换表示形式后出现问题:最长边小于短边;[%.16f, %.16f, %.16f, %.16f, %.1f]' % (
            x_c, y_c, longside, shortside, theta_longside))
            return False
        if (theta_longside < -180 or theta_longside >= 0):
            print('旋转框转换表示形式时出现问题:θ超出长边表示法的范围:[-180,0);[%.16f, %.16f, %.16f, %.16f, %.1f]' % (
            x_c, y_c, longside, shortside, theta_longside))
            return False
    
        return x_c, y_c, longside, shortside, theta_longside
    def longsideformat2cvminAreaRect(x_c, y_c, longside, shortside, theta_longside):
        '''
        trans longside format(x_c, y_c, longside, shortside, θ) to minAreaRect(x_c, y_c, width, height, θ)
        两者区别为:
                当opencv表示法中width为最长边时(包括正方形的情况),则两种表示方法一致
                当opencv表示法中width不为最长边 ,则最长边表示法的角度要在opencv的Θ基础上-90度
        @param x_c: center_x
        @param y_c: center_y
        @param longside: 最长边
        @param shortside: 最短边
        @param theta_longside: 最长边和x轴逆时针旋转的夹角,逆时针方向角度为负 [-180, 0)
        @return: ((x_c, y_c),(width, height),Θ)
                x_c: center_x
                y_c: center_y
                width: x轴逆时针旋转碰到的第一条边最长边
                height: 与width不同的边
                theta: x轴逆时针旋转与width的夹角,由于原点位于图像的左上角,逆时针旋转角度为负 [-90, 0)
        '''
        theta_longside=int(theta_longside)
        if (theta_longside >= -180 and theta_longside < -90):  # width is not the longest side
            width = shortside
            height = longside
            theta = theta_longside + 90
        else:
            width = longside
            height = shortside
            theta = theta_longside
    
        if theta < -90 or theta >= 0:
            print('当前θ=%.1f,超出opencv的θ定义范围[-90, 0)' % theta)
            return False
    
        return ((x_c, y_c), (width, height), theta)
    
    def xyxy2xywhn_new(x, w=640, h=640, clip=False, eps=0.0):
        # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] normalized where xy1=top-left, xy2=bottom-right
        if clip:
            clip_coords(x, (h - eps, w - eps))  # warning: inplace clip
        y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
        
        codinate_new=[]
        for i in y:
            codinate=[]
            point=np.array([(i[1],i[2]),(i[3],i[4]),(i[5],i[6]),(i[7],i[8])])
            rect = cv2.minAreaRect(point)
            c_x = rect[0][0]
            c_y = rect[0][1]
            w_label = rect[1][0]
            h_label = rect[1][1]
            theta = rect[-1]  # Range for angle is [-90,0)
            if(w==0 or h==0 ):
                continue
            trans_data = cvminAreaRect2longsideformat(c_x, c_y, w_label, h_label, theta)
            
            if not trans_data:
                continue
            else:
                c_x, c_y, longside, shortside, theta_longside = trans_data
                theta_label = int(theta_longside + 180.5)  # range int[0,180] 四舍五入
                if theta_label == 180:  # range int[0,179]
                    theta_label = 179
                if theta_label < 0 or theta_label > 179:
                    # print('id problems,问题出现在该图片中:%s' % (i, img_fullname))
                    print('出问题的longside形式数据:[%.16f, %.16f, %.16f, %.16f, %.1f]' % (
                        c_x, c_y, longside, shortside, theta_longside))
                    continue
                codinate.append(i[0])
                codinate.append(c_x/w)
                codinate.append(c_y/h)
                codinate.append(longside/w)
                codinate.append(shortside/h)
                codinate.append(theta_label)
                codinate_new.append(codinate)
                
        codinate_new=np.array(codinate_new)
        return codinate_new

    展开全文
  • 主要介绍了Python实现图片查找轮廓、多边形拟合、最小外接矩形代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 使用opencv画出图形的最小外接矩形与最小外接圆,首先求出图形的轮廓,设有滚动条可以选择最佳阈值,然后画出图形的最小外接圆与最小外接矩形,算法的效果很好!
  • 截取最小外接矩形

    2014-07-08 20:46:20
    利用帧间差分法对于经过处理后得到的图像作处理,得到了有一定角度倾斜的最小外接矩形
  • 没有方向角 x, y, w, h = cv2.boundingRect(c) cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) # 最小外接矩形框,有方向角 rect = cv2.minAreaRect(c) print(rect) box = np.int0(cv2.boxPoints...

    import cv2
    import numpy as np
    
    if __name__ == "__main__":
        orig = cv2.imread('mask.jpg', flags=cv2.IMREAD_COLOR)
        mask = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
        _, mask = cv2.threshold(mask, 200, 255, 0)
        image = orig.copy()
        contours, hierarchy = cv2.findContours(mask, mode=cv2.RETR_LIST, method=cv2.CHAIN_APPROX_SIMPLE)
        for c in contours:
            # 绘制轮廓
            image = cv2.drawContours(image, [c], 0, (255, 0, 0), 2)
            # 外接矩形框,没有方向角
            x, y, w, h = cv2.boundingRect(c)
            cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
            # 最小外接矩形框,有方向角
            rect = cv2.minAreaRect(c)
            print(rect)
            box = np.int0(cv2.boxPoints(rect))
            cv2.drawContours(image, [box], 0, (0, 0, 255), 2)
            # 绘制最小外接圆
            (x, y), radius = cv2.minEnclosingCircle(c)
            center = (int(x), int(y))
            radius = int(radius)
            cv2.circle(image, center, radius, (0, 255, 255), 2)
            # 用轮廓数据来拟合椭圆
            ellipse = cv2.fitEllipse(c)
            cv2.ellipse(image, ellipse, (255, 0, 255), 2)
            # 直线拟合
            rows, cols = image.shape[:2]
            [vx, vy, x, y] = cv2.fitLine(c, cv2.DIST_L2, 0, 0.01, 0.01)
            lefty = int((-x * vy / vx) + y)
            righty = int(((cols - x) * vy / vx) + y)
            image = cv2.line(image, (cols - 1, righty), (0, lefty), (0, 0, 255), 2)
            cv2.imshow("image", image)
            cv2.waitKey(0)
    

    原图

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,160
精华内容 2,464
热门标签
关键字:

一个矩形的最小外接矩形