美文网首页
Python OpenCV 基于图像边缘提取的轮廓发现函数

Python OpenCV 基于图像边缘提取的轮廓发现函数

作者: 梦想橡皮擦 | 来源:发表于2021-12-03 09:17 被阅读0次

    Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 36 篇。

    基础知识铺垫

    在图像中,轮廓可以简单的理解为连接具有相同颜色的所有连续点(边界)的曲线,轮廓可用于形状分析和对象检测、识别等领域。

    轮廓发现的原理:先通过阈值分割提取目标物体,再通过边缘检测提取目标物体轮廓。
    一个轮廓就是一系列的点(像素),这些点构成了一个有序的点集合。

    使用 cv2.findContours 函数可以用来检测图像的边缘。

    函数原型说明

    contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
    

    我使用的 Python OpenCV 是 4.0 以上版本,如果你使用的是 3.0 以上,可能存在返回值差异问题。
    参数说明如下:

    • image:输入图像;
    • mode:轮廓检索模式,具体说明参见后文;
    • method:轮廓逼近方法,具体说明参加后文;
    • contours:返回的轮廓;
    • hierachy:每条轮廓对应的属性;
    • offset:每个轮廓点移动的可选偏移量。

    备注:image 参数需要是二值图,而不是灰度图,返回结果是等高线和层次结构。

    轮廓检索模式,有四种

    • cv2.RETR_EXTERNAL:表示只检测外轮廓;
    • cv2.RETR_LIST:检测的轮廓,不建立等级关系;
    • cv2.RETR_CCOMP:建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层;
    • cv2.RETR_TREE:建立一个等级树结构的轮廓。
    • 上述内容,都可以在该网站查询:官网地址

    轮廓逼近方法

    • cv2.CHAIN_APPROX_NONE:存储所有的轮廓点,相邻的两个点的像素位置差不超过 1,即 max(abs(x1-x2),abs(y2-y1))==1,一般不会用到;
    • cv2.CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需 4 个点来保存轮廓信息。
    • cv2.CHAIN_APPROX_TC89_L1cv2.CV_CHAIN_APPROX_TC89_KCOS:使用 teh-Chinl chain 近似算法(没寻找资料学习)。

    了解上述内容之后,就可以应用轮廓发现函数了,代码如下:

    import cv2 as cv
    
    src = cv.imread("./both.jpeg")
    
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
    ret, thresh = cv.threshold(gray, 150, 255, 0)
    cv.imshow("thresh",thresh)
    # 寻找轮廓
    contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    

    轮廓发现之后,还要通过 cv2.drawContours 函数绘制轮廓,该函数原型如下:

    image = cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]])
    

    参数说明如下:

    • image:输入图像;
    • contours:轮廓,在 Python 中是一个 list,就是 cv2.findContours 函数找出来的点集,一个列表;
    • contourIdx:轮廓的索引,指定绘制轮廓 list 中的哪条轮廓,要绘制所有轮廓,请传递-1;
    • color:颜色;
    • thickness:厚度,如果是-1,表示填充;
    • lineType:线型;
    • hierarchy:层次结构的可选信息;
    • maxLevel:绘制轮廓的最大级别,0:仅绘制指定的轮廓,1:绘制轮廓和所有嵌套轮廓,2:绘制轮廓,所有嵌套轮廓,所有嵌套到嵌套的轮廓;
    • offset:轮廓偏移参数。

    测试代码与运行结果如下:

    import cv2 as cv
    # help(cv.drawContours)
    src = cv.imread("./both.jpeg")
    
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
    ret, thresh = cv.threshold(gray, 150, 255, 0)
    cv.imshow("thresh",thresh)
    # 寻找轮廓
    contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    
    # print(contours)
    # print(hierarchy)
    # 绘制轮廓
    cv.drawContours(src,contours,-1,(200,0,150),2)
    
    cv.imshow('src',src)
    cv.waitKey(0)
    
    20210209075346627[1].png

    橡皮擦的小节

    希望今天的 1 个小时你有所收获,我们下篇博客见~
    <font color=white size=2>私人联系方式:moshanba</font>
    使用大闪光术(CTRL+A)发现橡皮擦私人联系方式。

    相关阅读


    技术专栏

    1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧
    2. Python 爬虫小课,精彩 9 讲

    今天是持续写作的第 <font color="red">77</font> / 100 天。
    如果你有想要交流的想法、技术,欢迎在评论区留言。


    相关文章

      网友评论

          本文标题:Python OpenCV 基于图像边缘提取的轮廓发现函数

          本文链接:https://www.haomeiwen.com/subject/okspxrtx.html