zoukankan      html  css  js  c++  java
  • OpenCV4【13】轮廓检测与属性

    轮廓可以简单理解成 具有相同颜色或灰度的 连续的点 连成的曲线

    轮廓在形状分析、物体检测、物体识别 中很有用;

    注意

    1.为了准确,需要使用 二值化 图像,故需进行 阈值化处理 或 canny 边缘检测

    2.opencv 中与轮廓相关的函数 会改变原始图像

    轮廓检测与绘制

    def findContours(image, mode, method, contours=None, hierarchy=None, offset=None)

    image 是源图像,二值图;

    mode 是轮廓检索模式,可以是 list、tree、external;

    method 是轮廓点的编码方式,基本是链式编码;

    contours 返回的轮廓集合;

    hieracrchy 返回的轮廓层次关系;

    offset 点是否有位移;

    输出等高线和层次结构

    def drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)

    image是源图像,contours是所有等高线,contourIdx是第几个等高线,-1代表所有等高线

    color 代表颜色,thickness代表厚度或宽度,-1代表全部填充为 color

    示例

    img = cv.imread('imgs/fs3.jpg')
    
    ## 轮廓检测
    imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, imgthresh = cv.threshold(imgray, 127, 255, 0)
    contours, hierarchy = cv.findContours(imgthresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)  # 输入必须是二值图
    print(len(contours))
    
    ## 画轮廓
    # 画出所有轮廓
    # cv.drawContours(img, contours, -1, (0, 255, 0), 1)
    # 画出第4个轮廓
    # cv.drawContours(img, contours, 3, (0, 255, 0), 1)
    # 画出第4个轮廓
    cnt = contours[5]
    cv.drawContours(img, [cnt], 0, (0, 255, 0), 3)      # 线条加粗
    cv.imshow('img', img)
    # cv.waitKey(0)

    轮廓属性

    轮廓面积

    轮廓周长

    边界矩形

    轮廓矩和质心

    ## 轮廓面积
    for ind, val in enumerate(contours):
        area = cv.contourArea(val)
        if area > 0:
            print(ind, area)
            break
    
    cnt = contours[5]
    ## 轮廓周长
    perimeter = cv.arcLength(cnt, True)
    print(perimeter)
    
    ## 边界矩形
    x, y, w, h = cv.boundingRect(cnt)
    img = cv.rectangle(img, (x, y), (x + w, y + h), (255, 0, 255), 2)
    
    ## 轮廓矩和质心
    M = cv.moments(cnt)     #
    print(M)
    cx = int(M['m10']/M['m00'])     # 质心
    cy = int(M['m01']/M['m00'])
    cv.circle(img, (cx, cy), 5, (10, 255, 100), 8)      # 质心可视化
    cv.imshow('img', img)
    cv.waitKey(0)

    画在一起了 

    几何形状识别

    多边形逼近:通过对轮廓外形无限逼近,删除非关键点、得到轮廓的关键点,不断逼近轮廓真实形状的方法

    def approxPolyDP(curve, epsilon, closed, approxCurve=None)

    curve:轮廓,检测到的某个轮廓,也就是一个点集;

    epsilon:逼近曲率,越小,表示逼近的越厉害,越小,就会删掉更多非关键点

    closed:是否闭合

    多边形逼近后,判断多边形拐角个数,3个代表三角形,4个代表矩形,4-10代表多边形,大于10代表圆形

    示例

    img = cv.imread('imgs/flower.jpg')
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    cv.imshow('gray', gray)
    cv.waitKey(0)
    ret, binary = cv.threshold(gray, 80, 255, cv.THRESH_BINARY)
    cv.imshow('binary', binary)
    cv.waitKey(0)
    contours, hierarchy = cv.findContours(binary, mode=cv.RETR_TREE, method=cv.CHAIN_APPROX_SIMPLE)
    for ind, c in enumerate(contours):
        imgcopy = img.copy()
        cv.drawContours(imgcopy, contours, ind, (0, 0, 255), 2)
    
        ### 轮廓逼近
        epsilon = cv.arcLength(contours[ind], True)     # 周长
        if epsilon < 200: continue
        approx = cv.approxPolyDP(contours[ind], epsilon / 50, True) # 比周长小一点
    
        ### 几何形状
        corners = len(approx)
        print(corners)  # 3个拐角代表三角形,4个矩形,4-10多边形,大于10圆形
    
        # cv.imshow('img', np.hstack([gray, binary]))
        cv.imshow('img', imgcopy)
        cv.waitKey(0)

    输出 花的轮廓和几何形状

     

    参考资料: 

    https://www.cnblogs.com/mrfri/p/8550328.html   OpenCV+python轮廓

    https://www.cnblogs.com/zhangxiaoman/p/12390742.html  Python-Opencv 轮廓常用操作

    https://mp.weixin.qq.com/s/brp1yyPiCyQa-sDu2_mHHQ  OpenCV中几何形状识别与测量

  • 相关阅读:
    vue 相对其他热门 框架 优点 --- 待续
    vue router 只需要这么几步
    正则表达式
    MySQL数据库优化的八种方式
    Django REST Framework 最佳实践
    Node.js ZLIB
    Node.js 虚拟机
    Node.js 实用工具
    Node.js URL
    Node.js UDP/Datagram
  • 原文地址:https://www.cnblogs.com/yanshw/p/15499301.html
Copyright © 2011-2022 走看看