• 【OpenCV-Python】教程:3-9 轮廓(4)更多函数


    OpenCV Python 轮廓

    【目标】

    • 凸性缺陷查找
    • 点与多边形的关系
    • 不同形状的匹配

    【代码】

    在这里插入图片描述

    左图中红色点为凸性检测的缺陷点,即凹点
    右图为了验证点与多边形关系而做的图,也是官网要求做的练习。

    import cv2 
    import numpy as np 
    
    img = cv2.imread('star.png', 0)
    colorimg = cv2.imread('star.png', 1)
    convexHullImg = colorimg.copy()
    ret, thresh = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)
    
    # 寻找轮廓
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    cnt = contours[0]
    
    # 凸包
    hull = cv2.convexHull(cnt, returnPoints=False)
    defects = cv2.convexityDefects(cnt, hull)
    
    # 画出缺陷凹点
    for i in range(defects.shape[0]):
        startptidx, endptidx, farptidx, dis = defects[i, 0]
        startpt = tuple(cnt[startptidx][0])
        endpt = tuple(cnt[endptidx][0])
        farpt = tuple(cnt[farptidx][0])    
        cv2.line(convexHullImg, startpt, endpt, (0, 255, 255))
        cv2.circle(convexHullImg, farpt, 3, (0, 0, 255), 3)
    
    
    
    # 根据点在图像中和轮廓中的位置,画出颜色图
    polygonTestImg = colorimg.copy()
    # cv2.circle(polygonTestImg, (280, 180), 3, (0, 0, 255), 3)
    dist = cv2.pointPolygonTest(cnt, (50, 50), True)
    h, w, _ = polygonTestImg.shape
    
    # 在轮廓上,为白色
    bluevalue = 255
    redvalue = 255
    for j in range(h):
        for i in range(w):
            dist = cv2.pointPolygonTest(cnt, (i, j), True)
            if dist > 127:
                dist = 127
            
            if dist < -127:
                dist = -127
            
            if dist > 0:
                colorshow = (255 - dist * 2, 255 - dist * 2, 0)
            elif dist < 0:
                colorshow = (0, 255 + dist * 2, 255 + dist * 2)
            elif dist == 0:
                colorshow = (255, 255, 255)
            
            cv2.circle(polygonTestImg, (i, j), 2, colorshow, 2)
    
    cv2.imshow('convexHullImg', convexHullImg)
    cv2.imshow('polygonTestImg', polygonTestImg)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    在这里插入图片描述

    # 测试形状匹配
    import cv2
    import numpy as np 
    
    img1 = cv2.imread('star.png', 0)
    img2 = cv2.imread('box.png', 0)
    img3 = cv2.imread('testfit.png', 0)
    
    ret1, thresh1 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY)
    ret2, thresh2 = cv2.threshold(img2, 127, 255, cv2.THRESH_BINARY)
    ret3, thresh3 = cv2.threshold(img3, 127, 255, cv2.THRESH_BINARY)
    
    con1, hir1 = cv2.findContours(thresh1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    con2, hir2 = cv2.findContours(thresh2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    con3, hir3 = cv2.findContours(thresh3, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    
    cnt1 = con1[0]
    cnt2 = con2[0]
    cnt3 = con3[0]
    
    ret12 = cv2.matchShapes(cnt1, cnt2, cv2.CONTOURS_MATCH_I2, 0.0) 
    ret13 = cv2.matchShapes(cnt1, cnt3, cv2.CONTOURS_MATCH_I2, 0.0)
    ret23 = cv2.matchShapes(cnt2, cnt3, cv2.CONTOURS_MATCH_I2, 0.0)
    
    print(ret12, ret13, ret23)
    
    
    cv2.imshow('img1', img1)
    cv2.imshow('img2', img2)
    cv2.imshow('img3', img3)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    输出结果如下:

    0.05888818307213595 0.2987404256696341 1.6190198650037022
    
    • 1

    【接口】

    • convexityDefects
    void cv::convexityDefects	(	InputArray 	contour,
    InputArray 	convexhull,
    OutputArray 	convexityDefects 
    );
    
    • 1
    • 2
    • 3
    • 4
    cv2.convexityDefects(	contour, convexhull[, convexityDefects]	) ->	convexityDefects
    
    • 1

    计算查找一个轮廓的凸性缺陷

    • contour: 输入的轮廓
    • convexhull: 轮廓的凸包,用 convexHull
    • convexityDefects: 凸性缺陷输出向量, 每个缺陷是 4个整型元素的 vector。
    • pointPolygonTest
    double cv::pointPolygonTest	(	InputArray 	contour,
    Point2f 	pt,
    bool 	measureDist 
    );
    
    • 1
    • 2
    • 3
    • 4
    cv2.pointPolygonTest(	contour, pt, measureDist	) ->	retval
    
    • 1

    判断一个点是否在轮廓内或边缘上,计算其距离;正数在内部,负数在外部;
    如果 measureDist=false 则返回 1, -1, 0

    • contour: 输入的轮廓
    • pt: 测试点
    • measureDist: 如果为真,则计算距离,否则不用计算,只判断是否在内部还是外部;
    • matchShapes
    double cv::matchShapes	(	InputArray 	contour1,
    InputArray 	contour2,
    int 	method,
    double 	parameter 
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    cv2.matchShapes(	contour1, contour2, method, parameter	) ->	retval
    
    • 1

    比较两个形状

    • contour1: 第一个轮廓
    • contour2: 第二个轮廓
    • method: 比较的方法 见下 ShapeMatchModes
    • parameter: 方法的特殊参数(暂时不支持)
    • ShapeMatchModes

    在这里插入图片描述

    【OpenCV-Python】教程:3-9 轮廓(1)开始
    【OpenCV-Python】教程:3-9 轮廓(2)轮廓特征
    【OpenCV-Python】教程:3-9 轮廓(3)轮廓属性

    【参考】

    1. OpenCV官方文档
  • 相关阅读:
    多要素气象站:自动观测、数据可查
    【牛客 - 剑指offer】JZ43 整数中1出现的次数(从1到n整数中1出现的次数)两种方案 Java实现
    关于羊了个羊,我真的是娘了个娘。
    Git 客户端基本使用及新手常见问题
    c++类型转换和异常
    目标检测论文解读复现之十九:基于YOLOv5网络模型的人员口罩佩戴实时检测
    2024.6.13刷题记录
    基于SSM的爱心(慈善)捐献平台
    conan入门(二十七):因profile [env]字段废弃导致的boost/1.81.0 在aarch64-linux-gnu下交叉编译失败
    OpenAI 官方: 如何构建 Prompt 最佳策略
  • 原文地址:https://blog.csdn.net/zhoujinwang/article/details/128020367