OpenCV  4.10.0
开源计算机视觉
载入...
搜索中...
无匹配项
轮廓特征

上一个教程: 轮廓:开始
下一个教程: 轮廓属性

目标

  • 要找出轮廓的不同特征,如面积、周长、质心、边界框等。
  • 你将学习大量与轮廓相关的函数。

1. 矩

图像矩帮助你计算一些特征,如对象的重心、对象的面积等。查看维基百科页面上关于图像矩

我们使用函数:cv.moments (array, binaryImage = false)

参数
array栅格图像(单通道、8 位或浮点 2D 阵列)或 2D 点阵列(1×N 或 N×1)。
binaryImage如果它为真,则所有非零图像像素都将被视为 1。该参数仅用于图像。

试一试

从这些矩中,你可以导出有用的数据,如面积、质心等。质心由关系给出,\(C_x = \frac{M_{10}}{M_{00}}\) 并且 \(C_y = \frac{M_{01}}{M_{00}}\)。这可以通过如下方式完成

let cx = M.m10/M.m00
let cy = M.m01/M.m00

2. 轮廓面积

轮廓面积由函数cv.contourArea() 或从矩中M['m00']给出。

我们使用函数:cv.contourArea (contour, oriented = false)

参数
contour2D 点的输入向量(轮廓顶点)
oriented定向面积标志。如果为真,则该函数返回有符号面积值,具体取决于轮廓方向(顺时针或逆时针)。使用此功能,你可以通过获取面积的符号来确定轮廓的方向。默认情况下,该参数为假,这意味着返回绝对值。

试一试

3. 轮廓周长

它也被称为弧长。它可以通过使用cv.arcLength()函数来找出。

我们使用函数:cv.arcLength (curve, closed)

参数
curve2D 点的输入向量。
closed指示曲线是否为闭合曲线。

试试看

4. 轮廓逼近

它使用更少的顶点将轮廓形状逼近为其他形状,具体取决于我们指定的精度。它是道格拉斯-普克算法的实现。查看维基百科页面了解算法和演示。

我们使用以下函数:cv.approxPolyDP (曲线、逼近曲线、epsilon、闭合)

参数
curve存储在cv.Mat中的 2D 点输入矢量。
逼近曲线逼近结果。类型应与输入曲线的类型相匹配。
epsilon指定逼近精度的参数。这是原始曲线与其逼近之间的最大距离。
closed如果为 true,则逼近的曲线将闭合(其第一个和最后一个顶点相连)。否则,它不会闭合。

试试看

5. 凸包

凸包看起来与轮廓逼近类似,但实际上并非如此(在某些情况下,两者都会提供相同的结果)。在此,cv.convexHull()函数会检查曲线凸缺陷并予以纠正。一般来说,凸曲线始终凸出或至少是平坦的曲线。如果向内凸出,则称为凸缺陷。例如,查看下方的手部图像。红线显示手部的凸包。双向箭头标记表示凸缺陷,即轮廓的局部最大偏差。

图片

我们使用以下函数:cv.convexHull (点、包络、顺时针 = false、返回点 = true)

参数
输入的 2D 点集。
包络输出的凸包。
顺时针方向标志。如果为 true,则输出的凸包顺时针方向。否则,则逆时针方向。假定的坐标系 X 轴指向右侧,Y 轴指向上方。
返回点操作标志。对于矩阵,当标志为 true 时,该函数会返回凸包点。否则,它会返回凸包点的索引。

试试看

6. 检查凸性

有一个函数可以检查曲线是否凸出,即cv.isContourConvex()。它只会返回 True 或 False。并非什么大事。

cv.isContourConvex(cnt);

7. 边界矩形

有两种类型的边界矩形。

7.a. 直角边界矩形

它是一个直角矩形,它不考虑对象的旋转。因此边界矩形的面积不会是最小的。

我们使用函数:cv.boundingRect (points)

参数
输入的 2D 点集。

尝试

7.b. 旋转矩形

在这里,边界矩形以最小面积绘制,因此它会考虑旋转。

我们使用函数:cv.minAreaRect (points)

参数
输入的 2D 点集。

尝试

8. 最小包围圆

接下来,我们使用函数 cv.minEnclosingCircle() 找到对象的外切圆。这是一个完全覆盖面积最小的物体的圆。

我们使用函数:cv.minEnclosingCircle (points)

参数
输入的 2D 点集。

cv.circle (img, center, radius, color, thickness = 1, lineType = cv.LINE_8, shift = 0)

参数
img绘制圆的图像。
center圆心。
radius圆的半径。
color圆颜色。
thickness圆形轮廓的厚度,如果为正。负的厚度表示要绘制一个填充的圆。
lineType圆形边界的类型。
shift中心坐标和小数位数。

尝试

9. 拟合椭圆

下一步是将椭圆拟合到对象上。它返回椭圆所在的旋转矩形。我们使用函数:cv.fitEllipse (points)

参数
输入的 2D 点集。

cv.ellipse1 (img, box, color, thickness = 1, lineType = cv.LINE_8)

参数
img图像。
box通过 RotatedRect 替代椭圆表示。这意味着该函数绘制内切于旋转矩形内的椭圆。
color椭圆颜色。
thickness椭圆弧轮廓的厚度(如果为正)。否则,这表示绘制一个已填充的椭圆扇形。
lineType椭圆边界的类型。

尝试一下

10. 拟合曲线

类似地,我们可以对一组点拟合曲线。我们可以近似为一直线。

我们使用函数:cv.fitLine (点集、线、distType、param、reps、aeps)

参数
输入的 2D 点集。
线输出线参数。它应该是 4 个元素 [vx, vy, x0, y0] 的 Mat,其中 [vx, vy] 是与直线共线的归一化向量,[x0, y0] 是直线上的一个点。
distTypeM 估计器使用的距离(参见 cv.DistanceTypes)。
param针对某些类型的距离的数值参数 (C)。如果为 0,则选择一个最优值。
reps半径(坐标原点到直线的距离)的足够精度。
aeps角度的足够精度。0.01 将是 reps 和 aeps 的一个良好的默认值。

cv.line (img、pt1、pt2、颜色、厚度 = 1、线型 = cv.LINE_8、偏移 = 0)

参数
img图像。
pt1线段的第一个点。
pt2线段的第二个点。
color线颜色。
thickness线粗细。
lineType线的类型,。
shift点坐标中的分数位数。

尝试一下