• 基于OpenCV的轮廓检测(2)


    在本章中,我们将学习

    • 一些常用的属性,如Solidity,等效直径,掩模图像,平均强度等。
    • 质心(Centroid)、面积(Area)、周长(Perimeter)等也属于这一类,但我们在上一篇已经学习过
    • 凸度缺陷及如何找到它们。
    • 最短距离:从一个点到一个多边形的最短距离
    • 匹配不同的形状
    import cv2 as cv
    import numpy as np
    
    img = cv.imread('star.jpg', 0)
    ret2, thresh = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
    contours, hierarchy2 = cv.findContours(thresh, 1, 2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    # contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    cnt = contours[1]
    
    • 1
    • 2

    1. 横纵比

    在这里插入图片描述

    # 它是物体的边界矩形的宽度与高度之比。
    x, y, w, h = cv.boundingRect(cnt)
    aspect_ratio = float(w) / h
    
    • 1
    • 2
    • 3

    2.Extent

    在这里插入图片描述

    # Extent是等轮廓面积与边界矩形面积的比值。
    area = cv.contourArea(cnt)
    x, y, w, h = cv.boundingRect(cnt)
    rect_area = w * h
    extent = float(area) / rect_area
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.Solidity

    在这里插入图片描述

    # Solidity是轮廓面积与其凸包面积之比。
    area = cv.contourArea(cnt)
    hull = cv.convexHull(cnt)
    hull_area = cv.contourArea(hull)
    solidity = float(area) / hull_area
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.等效直径

    在这里插入图片描述

    # 等效直径是指面积与轮廓面积相等的圆的直径。
    area = cv.contourArea(cnt)
    equi_diameter = np.sqrt(4 * area / np.pi)
    
    • 1
    • 2
    • 3

    5.方向

    # 方向是物体所指向的角度。下面的方法也给出了长轴和短轴的长度。
    (x, y), (MA, ma), angle = cv.fitEllipse(cnt)
    
    • 1
    • 2

    6. 掩模和像素点

    # 在某些情况下,我们可能需要包含该对象的所有点。可以这样做:
    mask = np.zeros(img.shape, np.uint8)
    cv.drawContours(mask, [cnt], 0, 255, -1)
    pixelpoints = np.transpose(np.nonzero(mask))  # 转置
    
    • 1
    • 2
    • 3
    • 4
    # pixelpoints = cv.findNonZero(mask)
    # 这里给出了两个方法,一个使用Numpy函数,另一个使用OpenCV函数(最后一个注释行)来完成相同的操作。结果也是相同的,但略有不同。
    # Numpy给出了**(row, column)**格式的坐标,而OpenCV给出了**(x,y)**格式的坐标。所以基本上答案会互换。注意,row = y, column = x。
    
    • 1
    • 2
    • 3

    7.最大值最小值以及对应的位置

    # 我们可以通过掩膜图像找到这些参数。
    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(img, mask=mask)
    
    • 1
    • 2

    8.平均颜色或平均强度

    # 在这里,我们可以找到一个物体的平均颜色。也可以是灰度模式下物体的平均强度。我们再次使用相同的掩膜来完成。
    mean_val = cv.mean(img, mask=mask)
    
    • 1
    • 2

    9.极值点

    # 极值点是指物体的最上方、最下方、最右边和最左边的点。
    leftmost = tuple(cnt[cnt[:, :, 0].argmin()][0])
    rightmost = tuple(cnt[cnt[:, :, 0].argmax()][0])
    topmost = tuple(cnt[cnt[:, :, 1].argmin()][0])
    bottommost = tuple(cnt[cnt[:, :, 1].argmax()][0])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    请添加图片描述

    10.凸缺陷

    # 物体与凸包的任何偏差都可以被认为是凸缺陷。
    # OpenCV提供了一个现成的函数,cv.convexitydefects()。基本的函数调用如下所示:
    hull = cv.convexHull(cnt, returnPoints=False)
    defects = cv.convexityDefects(cnt, hull)
    
    • 1
    • 2
    • 3
    • 4
    # 记住,为了找到凸缺陷,我们必须传递returnPoints = False。
    # 它返回一个数组,其中每一行包含这些值—[起始点、结束点、最远点、到最远点的近似距离]。我们可以使用一个可视化图像。
    # 我们从开始点到结束点画一条线,然后在最远的点上画一个圆。记住,返回的前三个值是cnt的索引。所以我们必须从cnt中引入这些值。
    img = cv.imread('star.jpg')
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY_INV)
    contours, hierarchy = cv.findContours(thresh, 2, 1)
    cnt = contours[0]
    hull = cv.convexHull(cnt, returnPoints=False)
    defects2 = cv.convexityDefects(cnt, hull)
    for i in range(defects2.shape[0]):
        s, e, f, d = defects2[i, 0]
        start = tuple(cnt[s][0])
        end = tuple(cnt[e][0])
        far = tuple(cnt[f][0])
        cv.line(img, start, end, [0, 255, 0], 2)
        cv.circle(img, far, 5, [0, 0, 255], -1)
    cv.imshow('img', img)
    cv.waitKey(0)
    cv.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    请添加图片描述

    11.点多边形测试

    这个函数查找图像中一个点和轮廓线之间的最短距离。它返回距离,当点在轮廓外时为负,当点在轮廓内时为正,如果点在轮廓上则为零。

    # 例如,我们可以这样检查点(50,50):
    dist = cv.pointPolygonTest(cnt, (50, 50), True)
    
    • 1
    • 2

    在函数中,第三个参数是measureDist。如果它为真,它会找到带符号的距离。如果为False,它会查找点是在轮廓线内还是在轮廓线外(分别返回+1,-1,0)。
    如果你不想求距离,请确保第三个参数为False,因为这是一个耗时的过程。因此,将其设置为False将提供2-3倍的加速。

    12.形状匹配

    OpenCV附带了一个函数cv.matchShapes(),它使我们能够比较两个形状或两个轮廓,并返回一个显示相似性的指标。结果越低,说明匹配得越好。它是根据Hu矩计算的。文档中解释了不同的测量方法。

    img1 = cv.imread('star.jpg', 0)
    img2 = cv.imread('star2.jpg', 0)
    ret2, thresh = cv.threshold(img1, 127, 255, cv.THRESH_BINARY_INV)
    ret3, thresh2 = cv.threshold(img2, 127, 255, 0)
    contours, hierarchy = cv.findContours(thresh, 2, 1)
    cnt1 = contours[0]
    contours, hierarchy2 = cv.findContours(thresh2, 2, 1)
    cnt2 = contours[0]
    ret = cv.matchShapes(cnt1, cnt2, 1, 0.0)
    print(ret)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    # 我尝试匹配不同的形状,如下所示:
    # 我得到了以下结果:
    # 匹配图像A与自身= 0.0
    # 匹配图像A与图像B = 0.001946
    # 匹配图像A与图像C = 0.326911
    # 甚至图像旋转不影响结果
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参考目录

    https://docs.opencv.org/4.x/d5/d45/tutorial_py_contours_more_functions.html

  • 相关阅读:
    接口测试当中的权限限制测试和状态机测试【杭州多测师_王sir】【杭州多测师】...
    神经网络(十一)卷积运算DLC
    还在用Swagger?我推荐这款零代码侵入的接口管理神器
    柯西中值定理习题
    管道流:字节管道流、字符管道流
    7月更新 | Java on Azure Tooling
    【韩老师设计模式6】装饰者和组装模式。FilterInputStream 和 HashMap
    Vue父子组件传值(图解版)
    改进深度神经网络的产品制造周期预测
    在 Rust 中读取文件的 4 种方法
  • 原文地址:https://blog.csdn.net/weixin_43229348/article/details/125980634