python识别图像中绿色的部分_[OpenCV-Python] OpenCV 中的图像处理 部分 IV (四)

本文深入探讨了OpenCV中的轮廓处理,包括理解轮廓、查找和绘制轮廓,以及轮廓的近似方法。文章通过实例展示了如何使用cv2.findContours()和cv2.drawContours()函数,强调了轮廓在形状分析和物体识别中的重要性。同时,讲解了轮廓的特征,如面积、周长、重心、边界框等,并介绍了如何通过cv2.moments()计算矩和使用cv2.contourArea()计算面积。此外,还涵盖了轮廓的近似、凸包、凸性检测、边界矩形、最小外接圆、椭圆拟合、直线拟合等概念。最后,介绍了如何利用轮廓的层次结构进行形状匹配和层次分析。
摘要由CSDN通过智能技术生成

部分 IV

OpenCV 中的图像处理

21 OpenCV 中的轮廓

21.1 初识轮廓

目标

• 理解什么是轮廓

• 学习找轮廓,绘制轮廓等

• 函数:cv2.findContours(),cv2.drawContours()

21.1.1 什么是轮廓

轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同、的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。

• 为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理、或者 Canny 边界检测。

• 查找轮廓的函数会修改原始图像。如果你在找到轮廓之后还想使用原始图、像的话,你应该将原始图像存储到其他变量中。

• 在 OpenCV 中,查找轮廓就像在黑色背景中超白色物体。你应该记住,、要找的物体应该是白色而背景应该是黑色。

让我们看看如何在一个二值图像中查找轮廓:

函数 cv2.findContours() 有三个参数,第一个是输入图像,第二个是轮廓检索模式,第三个是轮廓近似方法。返回值有三个,第一个是图像,第二个是轮廓,第三个是(轮廓的)层析结构。轮廓(第二个返回值)是一个 Python列表,其中存储这图像中的所有轮廓。每一个轮廓都是一个 Numpy 数组,包含对象边界点(x,y)的坐标。

注意:我们后边会对第二和第三个参数,以及层次结构进行详细介绍。在那之前,例子中使用的参数值对所有图像都是适用的。

21.1.2 怎样绘制轮廓

函数 cv2.drawContours() 可以被用来绘制轮廓。它可以根据你提供的边界点绘制任何形状。它的第一个参数是原始图像,第二个参数是轮廓,一个 Python 列表。第三个参数是轮廓的索引(在绘制独立轮廓是很有用,当设置为 -1 时绘制所有轮廓)。接下来的参数是轮廓的颜色和厚度等。

在一幅图像上绘制所有的轮廓:

importnumpy as np

importcv2

im = cv2.imread('test.jpg')

imgray =cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

ret,thresh = cv2.threshold(imgray,127,255,0)

image, contours, hierarchy =cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

绘制独立轮廓,如第四个轮廓:

img = cv2.drawContour(img, contours, -1, (0,255,0), 3)

但是大多数时候,下面的方法更有用:

img = cv2.drawContours(img, contours, 3, (0,255,0), 3)

注意:最后这两种方法结果是一样的,但是后边的知识会告诉你最后一种方法更有用。

21.1.3 轮廓的近似方法

这是函数 cv2.findCountours() 的第三个参数。它到底代表什么意思呢?

上边我们已经提到轮廓是一个形状具有相同灰度值的边界。它会存贮形状边界上所有的 (x,y) 坐标。但是需要将所有的这些边界点都存储吗?这就是这个参数要告诉函数 cv2.findContours 的。

这个参数如果被设置为 cv2.CHAIN_APPROX_NONE,所有的边界点都会被存储。但是我们真的需要这么多点吗?例如,当我们找的边界是一条直线时。你用需要直线上所有的点来表示直线吗?不是的,我们只需要这条直线的两个端点而已。这就是 cv2.CHAIN_APPROX_SIMPLE 要做的。它会将轮廓上的冗余点都去掉,压缩轮廓,从而节省内存开支。我们用下图中的矩形来演示这个技术。在轮廓列表中的每一个坐标上画一个蓝色圆圈。第一个图显示使用 cv2.CHAIN_APPROX_NONE 的效果,一共 734 个点。第二个图是使用 cv2.CHAIN_APPROX_SIMPLE 的结果,只有 4 个点。看到他的威力了吧!

21.2 轮廓特征

目标

• 查找轮廓的不同特征,例如面积,周长,重心,边界框等。

• 你会学到很多轮廓相关函数

21.2.1 矩

图像的矩可以帮助我们计算图像的质心,面积等。详细信息请查看维基百科Image Moments。

函数 cv2.moments() 会将计算得到的矩以一个字典的形式返回。如下:

importcv2importnumpy as np

img= cv2.imread('star.jpg',0)

ret,thresh= cv2.threshold(img,127,255,0)

contours,hierarchy= cv2.findContours(thresh, 1, 2)

cnt=contours[0]

M=cv2.moments(cnt)print M

根据这些矩的值,我们可以计算出对象的重心:

   和    

. 。

#This can be done as follows:

cx = int(M['m10']/M['m00'])

cy= int(M['m01']/M['m00'])

21.2.2 轮廓面积

轮廓的面积可以使用函数 cv2.contourArea() 计算得到,也可以使用矩(0 阶矩),M['m00']。

area = cv2.contourArea(cnt)

21.2.3 轮廓周长

也被称为弧长。可以使用函数 cv2.arcLength() 计算得到。这个函数的第二参数可以用来指定对象的形状是闭合的(True),还是打开的(一条曲线)。

perimeter = cv2.arcLength(cnt,True)

21.2.4 轮廓近似

将轮廓形状近似到另外一种由更少点组成的轮廓形状,新轮廓的点的数目由我们设定的准确度来决定。使用的Douglas-Peucker算法,你可以到维基百科获得更多此算法的细节。

为了帮助理解,假设我们要在一幅图像中查找一个矩形,但是由于图像的种种原因,我们不能得到一个完美的矩形,而是一个“坏形状”(如下图所示)。

现在你就可以使用这个函数来近似这个形状()了。这个函数的第二个参数叫epsilon,它是从原始轮廓到近似轮廓的最大距离。它是一个准确度参数。选择一个好的 epsilon 对于得到满意结果非常重要。

epsilon = 0.1*cv2.arcLength(cnt,True)

approx= cv2.approx

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值