Opencv图像轮廓处理
@fuxianjun

寻找轮廓的操作一般用于二值化图,所以通常会使用阈值分割或Canny边缘检测先得到二值图。
cv2.findContours()函数
contours,hierarchy=cv2.findContours(image,mode,method)
contours:返回的轮廓。例如contours[i]表示第i个轮廓。
hierarchy:图像的拓扑信息(轮廓层次)。
image:输入的图像。
mode:轮廓搜索模式:决定了轮廓的提取方式。
method:轮廓近似方法:决定了如何表达轮廓。
例如:img=cv2.drawContours(img,contours,-1,(0,255,0),5)绿色轮廓线,线条粗细为5(若为-1,则会将轮廓内部进行填充)
矩特征
比较两个轮廓最简单的方法是比较二者的轮廓矩。轮廓矩代表了一个轮廓、一幅图像、一组点集的全局特征。矩信息包含了对应对象不同类型的几何特征,例如大小、位置、角度、形状等。矩特征被广泛地应用在模式识别、图像识别等方面。
retval=cv2.moments(array[,binaryImage]
array:可以是点集,也可以是灰度图像或者二值图像。
binaryImage:当为True时,array内所有的非零值都会被处理为1.
计算结果m00表示面积。
计算轮廓的面积:
area=cv2.contourArea(contour [, oriented])
contour :轮廓。
oriented:布尔值,当为True时,表示顺时针或逆时针计算.
计算轮廓的长度:
length=cv2.arcLength(curve,closed)
curve :轮廓。
closed :布尔值,当为True时,表示闭合.
Hu特征:
Hu矩是归一化中心矩的线性组合,Hu矩再图像旋转,缩放,平移等操作后,仍能保持矩的不变性,经常使用 Hu 矩来识别图像的特征。在 OpenCV 中,使用函数 cv2.HuMoments()可以得到 Hu 距。该函数使用 cv2.moments()函数的返回值作为参数,返回 7 个 Hu 矩值。
通过Hu 矩可以来判断两个对象的一致性。但是结果比较抽象,
OpenCV 提供了 cv2.matchShapes() 对两个对象的Hu矩进行比较。
retval = cv2.matchShapes(contour1, contour2, method, 0.0)
contour1 :第一个轮廓或灰度图像。
contour2:第二个灰度或轮廓图像。
method :比较两个对象的Hu 矩的方法,写1吧

矩形包围框:
retval = cv2.boundingRect( array )
retval:矩形边界左上角顶点的坐标值及矩形边界的宽度和高度。
contour2:第二个灰度或轮廓图像。
method :比较两个对象的Hu 矩的方法,写1吧

最小外包矩形框:
retval =cv2.minAreaRect( points )
retval:回的矩阵特征信息,结构是(最小外接矩形的中心(x,y),(宽度,高度),旋转角度)。
points:轮廓。

最小包围圆形:
center, radius = cv2.minEnclosingCircle( points )
center:圆形。
radius:半径。
points:轮廓。

最优拟合椭圆:
retval = cv2.fitEllipse( points )
center:RotatedRect 类型的值,这个是拟合椭圆的外界矩形,包含外接矩形的
质心,宽,高,旋转角度等参数信息,这些信息与椭圆的中心点,轴长度,旋转角
度等信息吻合。
points:轮廓。

最优拟合直线:
line = cv2.fitLine( points, distType, param, reps, aeps )

逼近多边形:
在数字化时,要对曲线进行采样,即在曲线上取有限个点,将其变为折线,并且能够在一定程度上保持原有的形状。
approx = cv2.approxPolyDP(contour[0],epsilon,True)

运用以上函数实现读取手掌轮廓
import cv2
import numpy as np
img=cv2.imread("hand.png")
gray1-cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,binary1=cv2.threshold(gray1,20,250,0)
contours,h=cv2.findContours(binary1,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
cnt=contours[0]
cnt=cv2.arclength(contours[0],True)
approx1=cv2.approxPolyDP(contours[0],cnt,True)
img=cv2.polylines(adp,[approx1],True,(0,255,0),1)
cv2.imshow("xxw",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

