图像轮廓之轮廓拟合
《OpenCV轻松入门:面向Python》读书笔记
作者:李立宗
出版社:电子工业出版社
出版时间:2019-05
第12章 图像轮廓
12.4 轮廓拟合
在计算轮廓时,可能并不需要实际的轮廓,而仅需要一个接近于轮廓的近似多边形。OpenCV提供了多种计算轮廓近似多边形的方法。
1)矩形包围框
函数cv2.boundingRect()能够绘制轮廓的矩形边界。该函数的语法格式为:
retval=cv2.boundingRect(array)
式中:
- 返回值retval表示返回的矩形边界的左上角顶点的坐标值及矩形边界的宽度和高度。
- 参数array是灰度图像或轮廓。
该函数还可以是具有4个返回值的形式:
x,y,w,h=cv2.boundingRect(array)
这里的4个返回值分别表示:
- 矩形边界左上角顶点的x坐标。
- 矩形边界左上角顶点的y坐标。
- 矩形边界的x方向的长度。
- 矩形边界的y方向的长度。
2)最小包围矩形框
函数cv2.minAreaRect()能够绘制轮廓的最小包围矩形框,其语法格式为:
retval=cv2.minAreaRect(array)
式中:
- 返回值retval表示返回的矩形特征信息。该值的结构是(最小外接矩形的中心(x, y), (宽度,高度),旋转角度)。
- 参数points是轮廓。
3)最小包围圆形
函数cv2.minEnclosingCircle()通过迭代算法构造一个对象的面积最小包围圆形。该函数的语法格式为:
center,radius=cv2.minEnclosingCircle(points)
式中:
- 返回值center是最小包围圆形的中心。
- 返回值radius是最小包围圆形的半径。
- 参数points是轮廓。
4)最优拟合椭圆
在OpenCV中,函数cv2.fitEllipse()可以用来构造最优拟合椭圆。该函数的语法格式是:
retval=cv2.fitEllipse(points)
式中:
- 返回值retval是RotatedRect类型的值。这是因为该函数返回的是拟合椭圆的外接矩形,retval包含外接矩形的质心、宽、高、旋转角度等参数信息,这些信息正好与椭圆的中心点、轴长度、旋转角度等信息吻合。
- 参数points是轮廓。
5)最优拟合直线
在OpenCV中,函数cv2.fitLine()用来构造最优拟合直线,该函数的语法格式为:
line=cv2.fitLine(points,distType,param,reps,aeps)
式中line为返回值,是返回的最优拟合直线参数。
式中的参数如下:
- points:轮廓。
- distType:距离类型。拟合直线时,要使输入点到拟合直线的距离之和最小
- param:距离参数,与所选的距离类型有关。当此参数被设置为0时,该函数会自动选择最优值。
- reps:用于表示拟合直线所需要的径向精度,通常该值被设定为0.01。
- aeps:用于表示拟合直线所需要的角度精度,通常该值被设定为0.01。
6) 最小外包三角形
在OpenCV中,函数cv2.minEnclosingTriangle()用来构造最小外包三角形。该函数的语法格式为:
retval,triangle=cv2.minEnclosingTriangle(points)
式中有两个返回值:
- retval:最小外包三角形的面积。
- triangle:最小外包三角形的三个顶点集。
式中的参数points是轮廓。
7)逼近多边形
函数cv2.approxPolyDP()用来构造指定精度的逼近多边形曲线。该函数的语法格式为:
approxCurve=cv2.approxPolyDP(curve,epsilon,closed)
式中,返回值approxCurve为逼近多边形的点集。
式中的参数如下:
- curve是轮廓。
- epsilon为精度,原始轮廓的边界点与逼近多边形边界之间的最大距离。
- closed是布尔型值。该值为True时,逼近多边形是封闭的;否则,逼近多边形是不封闭的。
8)示例
【例12.16】使用函数cv2.fitEllipse()构造最优拟合椭圆。
import cv2
o = cv2.imread('cc.bmp')
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,
cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow("original",o)
ellipse = cv2.fitEllipse(contours[0])
print("ellipse=",ellipse)
cv2.ellipse(o,ellipse,(0,255,0),3)
cv2.imshow("result",o)
cv2.waitKey()
cv2.destroyAllWindows()