zoukankan      html  css  js  c++  java
  • opencv 绘制图像轮廓

    图像轮廓概念

    轮廓是一系列相连的点组成的曲线,代表了物体的基本外形。
    谈起轮廓不免想到边缘,它们确实很像。简单的说,轮廓是连续的,边缘并不全都连续(下图)。其实边缘主要是作为图像的特征使用,比如可以用边缘特征可以区分脸和手;而轮廓主要用来分析物体的形态,比如物体的周长和面积等,可以说边缘包括轮廓
    理解图像边缘和轮廓
    寻找轮廓的操作一般用于二值图像,所以通常会使用阈值分割或Canny边缘检测先得到二值图。

    注意:寻找轮廓是针对白色物体的,一定要保证物体是白色,而背景是黑色,不然很多人在寻找轮廓时会找到图片最外面的一个框。

    opencv找出图像轮廓

    使用cv.findContours()寻找轮廓:

    import cv2 as cv
    import numpy as np
    
    img = cv.imread('j.png')
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, thresh = cv.threshold(img_gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)
    
    # 寻找二值图像的轮廓
    contours, hierarchy = cv.findContours(
        thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    
    print(len(contours))
    
    • 参数2:轮廓的查找方式,一般使用cv.RETR_TREE,表示提取所有的轮廓并建立轮廓间的层级。
    • 参数3:轮廓的近似方法。比如对于一条直线,我们可以存储该直线的所有像素点,也可以只存储起点和终点。使用cv.CHAIN_APPROX_SIMPLE就表示用尽可能少的像素点表示轮廓。
    • 简便起见,这两个参数也可以直接用真值3和2表示。
    • 函数有2个返回值,hierarchy是轮廓间的层级关系,这个不用理会。我们主要看contours,它就是找到的轮廓了,以链表形式存储,记录了每条轮廓的所有像素点的坐标(x,y)。
      图解函数返回值contours

    opencv绘制图像轮廓

    轮廓找出来后,可以像图中那样用红色画出来:cv.drawContours()

    cv.drawContours(img, contours, -1, (0, 0, 255), 2)
    其中参数2就是得到的contours,参数3表示要绘制哪一条轮廓,-1表示绘制所有轮廓,参数4是颜色(B/G/R通道,所以(0,0,255)表示红色),参数5是线宽。

    经验之谈:很多人画图时明明用了彩色,但没有效果,请检查你是在哪个图上画,画在灰度图和二值图上显然是没有彩色的。

    一般情况下,我们会首先获得要操作的轮廓,再进行轮廓绘制及分析:
    cnt = contours[1]
    cv.drawContours(img, [cnt], 0, (0, 0, 255), 2)

    实验:找出并绘制图像轮廓

    import cv2 as cv
    import numpy as np
    
    img = cv.imread('jiao.jpg')
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    ret, thresh = cv.threshold(img_gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)
    
    # 寻找二值图像的轮廓
    contours, hierarchy = cv.findContours(
        thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    cnt = contours[1:6]
    
    cv.drawContours(img, cnt, -1, (0, 0, 255), 2)
    
    cv.imshow('result',img)
    cv.waitKey(0)
    cv.destroyAllWindows()
    

    实验结果

    用红色标出部分图像轮廓

  • 相关阅读:
    Sublime Text 试玩日记
    Makefile 学习
    小书匠使用手册
    较完整的解决Linux zip 压缩包中文我乱码问题
    彻底解决Android模拟器中文短信乱码问题
    博客变更
    关于如何学习一个框架的经验总结
    [JavaScript] this、call和apply详解
    类与类之间关系,用C#和JavaScript体现
    [Node.js] require背后的故事
  • 原文地址:https://www.cnblogs.com/wojianxin/p/12600958.html
Copyright © 2011-2022 走看看