图像轮廓


边缘检测可以检测出边缘信息,但可能边缘不连续,而轮廓检测可以将边缘形成一个整体,便于后续处理。
Opencv中提供了查找图像轮廓的函数cv2.findContours(),其能查找图像的轮廓信息;cv2.drawContours()能将轮廓画出来。

一.查找并绘制轮廓

1.查找图像轮廓

函数cv2.findContours()的语法格式为:

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

函数参数说明:

(1)返回值contours

返回的是一组轮廓信息,类型为list,但其每个元素的类型为ndarray。其内的每一个元素为一个轮廓,而每一个轮廓由若干点组成。我们可以通过contours[i]来获取图像第i个轮廓的信息。可以用len(contours)来获取其轮廓的个数。

(2)返回值hierarchy

描述不同轮廓之间的层次关系,每个轮廓都含有一个列表来描述当前轮廓所在的层次,形式为:

【Next,Previous,First_child,Parent】
	各元素的含义:
		Next:后一个轮廓的索引编号
		Previous:前一个轮廓的索引编号
		First_child:第一个子轮廓的索引编号
		Parent:父轮廓的索引编号
	若对应元素关系不存在时,则该参数的值为-1
(3)输入参数image

输入图像,一般情况下都是将图像处理为二值图像之后,再讲其作为image参数使用

(4)输入参数mode

其决定轮廓的提取方式,具体为:
1. cv2.RETR_EXTERNAL:只检测外轮廓
2. cv2.RETR_LIST:对检测到的轮廓不建立等级关系
3. cv2.RETR_CCOMP:检索所有轮廓并将他们组织为两级层次结构。上面一层为外边界,下面一层为内孔边界。
4. cv2.RETR_TREE:建立一个等级树结构的轮廓

(5)输入参数method

其决定如何表示轮廓,具体为:
1. cv2.CHAIN_APPROX_NONE:存储所有的轮廓点,相邻两像素点的位置不超过1。
2. cv2.CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向和对角方向的元素,只保留该方向的终点坐标。例如,对一个矩形,可以用四个点保存其轮廓信息。

2.绘制图像轮廓

cv2.drawContours()绘制图像轮廓,其语法格式:

image=cv2.drawContours(image,contours,contourIdx,color)

参数说明:
image:待绘制轮廓的图像
contours:需要绘制的轮廓,list类型,里面含有多个轮廓信息
contoursIdx:需要绘制轮廓的索引,可以指定需绘制的轮廓,若其为负数,则表明要绘所有的轮廓。
color:绘制轮廓的颜色,用BGR来表示。

3.实例

import cv2
image=cv2.imread("wb3.png")
image2=image.copy()
image1=image.copy()
image1=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
retval,image1=cv2.threshold(image1,127,255,cv2.THRESH_BINARY_INV)
contours,hierarchy=cv2.findContours(image1,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)
o=cv2.drawContours(image,contours,-1,(0,0,255))
cv2.imshow("image",image2)
cv2.imshow("edge",o)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述

二.矩特征

比较两个轮廓最简单的方法为比较二者的轮廓矩。轮廓矩含有对象不同类型的几何特征。

1.轮廓矩的计算

Opencv提供了函数cv2.moments()来获取图像的moments特征。使用轮廓矩可以方便的比较两个轮廓。
函数语法:

retval=cv2.moments(array[,binaryimage])

参数说明:
array:可以是点集,也可以是灰度图像或者二值图像。当array为点集时,其会把这些点集当做轮廓中的顶点。
binaryimage:该参数为True时,图像内所有非零值处理为1。
retval:返回值,其类型为dict,常用的几个键值为:
mm0:零阶矩,代表边缘轮廓面积
中心矩:
二阶中心矩:mu20,mu11,mu02
三阶中心矩:mu30,mu21,mu12,mu03
归一化中心矩
二阶Hu矩:nu20,nu11,nu02
三阶Hu矩:nu30,nu21,nu12,nu03
中心矩具有平移不变性
归一化中心矩具有缩放不变性

2.计算轮廓面积

cv2.contourArea()用于计算轮廓面积,其语法:

retval=cv2.contourArea(contour[,oriented])

参数说明:
retval:轮廓面积
contour:轮廓
oritented:为True是,结果带正负号,表明轮廓是顺时针还是逆时针。默认为False,返回面积的绝对值。

3.计算轮廓周长

cv2.arcLength()用于计算轮廓面积,其语法:

retval=cv2.arcLength(curve[,closed])

参数说明:
retval:轮廓周长
curve:轮廓
closed:用来表示轮廓是否封闭。为True时,表示轮廓是封闭的。

三.轮廓近似

cv2.approxPolyDP()函数对图像轮廓进行多边近似,类似于二分。函数语法格式:

retval=cv2.approxPolyDP(cnt,epsilon,True)

参数:
retval:近似后的轮廓值
cnt:原始轮廓
epsilon:阈值

实例:

import cv2
image=cv2.imread("jh3.png")
image2=image.copy()
image1=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
contours,hierarchy=cv2.findContours(image1,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt=contours[1]
epsilon1=0.1*cv2.arcLength(cnt,True)
epsilon2=0.001*cv2.arcLength(cnt,True)
res1=cv2.approxPolyDP(cnt,epsilon1,True)
res2=cv2.approxPolyDP(cnt,epsilon2,True)
o1=cv2.drawContours(image2,[res1],-1,(0,0,255))
o2=cv2.drawContours(image,[res2],-1,(0,0,255))
cv2.imshow("o1",o1)
cv2.imshow("o2",o2)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述
可以观察到,epsilon(阈值)不同,得到结果不同,且阈值越小,得到的近似图形越精确。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值