openCV Contours详解

在OpenCV中处理结构分析和形状描述(Structural Analysis and Shape Descriptors),大部分跟contours相关。
轮廓线就是一条连接所有边界点的曲线,其实也就是两点相连构成的list。
(部分翻译的外文blog)

“The contours are a useful tool for shape analysis and object detection and recognition”


`import numpy as np
import cv2
 #找出下图的轮廓线。
im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)`

openCV Contours详解_第1张图片

轮廓线生成的函数findContours,需要考虑3点:
1、使用binary images
2、转换threshold
3、轮廓是指白色物体的轮廓,背景是黑色。

contours的结构

不同的物体表示成不同的list,list里保存每个轮廓点。要知道有几个物体,可以使用len查看。

>>>len(contours)
#output = 1 using the above picture

>>> cnt = contours[0]
>>> len(cnt)

画轮廓线

#轮廓线线宽3pixel
cv2.drawContours(im,contours,-1,(0,255,0),3)

#轮廓线线宽-1,表示填充物体
cv2.drawContours(im,contours,-1,(0,255,0),-1)

#可以单独画其中某一个物体的轮廓线,用[cnt]替换contours
cv2.drawContours(im,[cnt],0,(255,0,0),-1)

画mask

mask是指制图区域,或者ROI(region of interest)。


for h,cnt in enumerate(contours):
    mask = np.zeros(imgray.shape,np.uint8)
    cv2.drawContours(mask,[cnt],0,255,-1)
    mean = cv2.mean(im,mask = mask)

openCV Contours详解_第2张图片
接下来我们来看看几个跟contours相关的常用函数。

Moments函数

这个函数可以计算形状的中心点、面积等性质。
`

moments = cv2.moments(cnt)

`


{'mu02': 10888082.359906793, 'mu03': 0.005234025965704581, 'm11': 368666693.125,
'nu02': 0.10815497152071127, 'm12': 69763579350.98334, 'mu21': 101313.30416250229, 'mu20': 6674463.831166983,
'nu20': 0.06629968636479547, 'm30': 84692116672.95001, 'nu21': 1.0046975468372928e-05, 'mu11': -1980114.5675549507,
'mu12': -33122544.260385513, 'nu11': -0.019669141689288665, 'nu12': -0.0032846761082870463, 'm02': 352044973.5833333,
'm03': 68983799276.15001, 'm00': 10033.5, 'm01': 1850134.5, 'mu30': 8633090.369003296, 'nu30': 0.0008561209988226333,
'm10': 2010061.8333333333, 'm20': 409360323.5833333, 'm21': 74691021944.88333}

其中‘m00’表示面积

##Contour Area函数

计算contour包含的面积,也就是像素点的个数。
area = cv2.contourArea(cnt)

contour Perimeter

#计算长度
perimeter = cv2.arcLength(cnt,True)

contour Approximation

该函数可以减少轮廓边的小毛刺

#乘法前面的参数叫epsilon,表示原始轮廓线到新轮廓线的最大距离,可以控制新轮廓线的形状。
approx = cv2.approxPolyDP(cnt,0.1*cv2.arcLength(cnt,True),True)

convex hull

凸壳可以找到物体最大外接凸多边形。

#这个函数比较复杂,用到的时候需要再具体看看。
#以下是函数表达式。
hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]]])
#正常的获取轮廓的凸壳可以直接调用:

hull = cv2.convexHull(cnt)

#还有一个参数returnPoints,表示返回的是cnt的列表序号而不是直接返回坐标,默认是true,返回的坐标
hull = cv2.convexHull(cnt,returnPoints = False)

is contour convex

#返回真or假
k = cv2.isContourConvex(cnt)

bounding rectangle

openCV Contours详解_第3张图片

第一种:外接矩形框,矩形是跟图片平行的,(x,y)框的左上坐标,(w,h)表示宽度和高度。


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

第二种:最小外接矩形框

#返回值 Box2D structure - (x,y),(w,h),theta.
矩形中心点,theta旋转角度
rect = cv2.minAreaRect(cnt)
box = cv2.cv.BoxPoints(rect)
box = np.int0(box)
cv2.drawContours(im,[box],0,(0,0,255),2)

#BoxPoints是把中心点,长宽角度转换成四个角点坐标。

最小外接圆minEnclosingCircle

最小外接圆形


(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(im,center,radius,(0,255,0),2)

fitEllipse外接矩形的内接椭圆


ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(im,ellipse,(0,255,0),2)

openCV Contours详解_第4张图片

你可能感兴趣的:(图像视觉,opencv)