OpenCV-python学习笔记---轮廓

本文详细介绍了在OpenCV-Python中如何生成、绘制轮廓,包括使用函数获取和绘制轮廓的方法,以及如何利用轮廓特性计算面积、周长、图像矩、最大外接矩形和最小外接圆等关键信息。

轮廓的生成

主要涉及两个函数findContours(),分别用于获得轮廓和绘制轮廓。

先看第一个函数,用途是获取轮廓,函数原型是:cv2.findContours

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

代码示例:

contours,hierarchy = cv2.findContours(thres,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

print(hierarchy)
[[[ 1 -1 -1 -1]
  [ 2  0 -1 -1]
  [ 3  1 -1 -1]
  [-1  2 -1 -1]]]

参数解读:

  • image:输入该函数的图片必须是二值图,要想从灰度图和彩色图获得二值图,可使用 compare, inRange, threshold , adaptiveThreshold, Canny等方法。

  • hierarchy:可选的输出向量,包含图像轮廓层级结构的信息(如果轮廓a被轮廓b包围,则称a是b的子轮廓;如果二者互不干扰,则称两者处于同一层级),向量中元素的个数和轮廓的个数一致,每个元素包含四个值[next,previous,child,parent]。next/previous表示同一层级的下/上一条轮廓,child表示该轮廓的第一个子轮廓,parent表示该轮廓的父轮廓。

  • contours:列表,包含所有轮廓的坐标。

  • mode:轮廓检索模式,参考RetrievalModes,一般使用cv2.RETR_TREE,保留轮廓的所有层级信息。

  • method:轮廓近似方法,参考ContourApproximationModes

  • offset:可选,表示轮廓每个点的偏移量。

轮廓的绘制

第二个函数cv2.drawContours用于绘制轮廓,函数原型是:

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

代码示例:cv2.drawContours(img,contours,-1,(0,0,255))
在这里插入图片描述
参数解读:

  • image:输入图片。
  • contours:轮廓数组。
  • contourIdx:轮廓下标,如果为负值表示绘制所有轮廓。
  • color:轮廓颜色。
  • thickness:轮廓粗细。
  • lineType:轮廓线条类型。
  • hierarchy:轮廓层级。
  • maxlevel:当hierarchy参数被起用时,maxlevel参数才有效。如果设置为0,表示只绘制最底层轮廓,设置为1,表示再绘制上一层级的轮廓,设置为2,再绘制上上层级的轮廓,以此类推。

maxlevel参数示例:对于下面一张图片
在这里插入图片描述
运行代码,可知图中轮廓有672个层级。

contours,hierarchy = cv2.findContours(thres,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
print(hierarchy.shape[1]) #672

获得轮廓和轮廓层级后,使用drawContours函数绘制轮廓。设置maxlevel=1时,结果如下:
在这里插入图片描述
设置maxlevel=50时,绘制的轮廓如下:
在这里插入图片描述

轮廓的特征

对于以下轮廓:
在这里插入图片描述
contourArea()计算轮廓面积,函数原型是:

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

代码示例:

area = cv2.contourArea(cnt,oriented=False)
print(area) #4386.5

oriented参数用于判断轮廓是顺时针还是逆时针,当oriented=True时,返回一个有符号数。

area = cv2.contourArea(cnt,oriented=True)
print(area) #-4386.5

arcLength()计算轮廓周长或曲线长度,函数原型是:

retval = cv2.arcLength(curve, closed)

closed参数表示曲线是否闭合,代码示例:

primeter = cv2.arcLength(cnt,True)
print(primeter) #585.7716399431229

使用moment()函数返回一个字典,存储轮廓的图像矩(image moment),关于图像矩的概念,参考Image moment
函数原型:

retval = cv.moments(array[, binaryImage])

代码示例:

moment = cv2.moments(cnt)
print(type(moment))

{'m00': 4386.5, 'm10': 901090.1666666666, 'm01': 1236138.8333333333, 'm20': 188838763.0833333, 'm11': 257499174.375, 'm02': 356134618.0833333, 'm30': 40295080579.05, 'm21': 54657354898.55, 'm12': 75190459423.68333, 'm03': 104935417053.65001, 'mu20': 3733670.534977913, 'mu11': 3567213.2781181633, 'mu02': 7784175.754667103, 'mu30': -30805687.716514587, 'mu21': -23983275.523046732, 'mu12': 21521982.85149741, 'mu03': 187559951.4465332, 'nu20': 0.19404377951994134, 'nu11': 0.185392776452854, 'nu02': 0.4045538752636705, 'nu30': -0.024173279544299146, 'nu21': -0.018819720206919972, 'nu12': 0.016888339341892225, 'nu03': 0.14717863724891386}

字典中每个参数的计算方式,参考cv::Moments

使用boundingRect()函数返回轮廓的最大外接矩形,函数原型是:

retval = cv.boundingRect(array)

代码示例:

rect = cv2.boundingRect(cnt)
x,y,w,h = rect
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

结果如图所示:
在这里插入图片描述
使用minAreaRect()函数找到最小外接矩形,代码示例:

min_rect = cv2.minAreaRect(cnt)
box = np.int0(cv2.boxPoints(min_rect))  # 矩形的四个角点取整
cv2.drawContours(img, [box], 0, (255, 0, 0), 2)

结果如下:
在这里插入图片描述
使用minEnclosingCircle()找到最小外接圆,代码示例:

(x, y), radius = cv2.minEnclosingCircle(cnt)
(x, y, radius) = np.int0((x, y, radius))  # 圆心和半径取整
cv2.circle(img, (x, y), radius, (0, 0, 255), 2)

结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值