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

上一个教程: 轮廓:入门
下一个教程: 轮廓属性

目标

  • 找到轮廓的不同特征,例如面积、周长、质心、边界框等
  • 您将学习许多与轮廓相关的函数。

1. 矩

图像矩可帮助您计算一些特征,例如物体的质心、物体的面积等。请查看维基百科上的图像矩

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

参数
array栅格图像(单通道、8 位或浮点 2D 数组)或 2D 点的数组(1×N 或 N×1)。
binaryImage如果为 true,则所有非零图像像素都视为 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 (轮廓, oriented = false)

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

尝试一下

3. 轮廓周长

也称为弧长。可以使用 cv.arcLength() 函数找到。

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

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

尝试一下

4. 轮廓近似

它根据我们指定的精度,将轮廓形状近似为顶点数量较少的另一个形状。它是 Douglas-Peucker 算法 的实现。查看维基百科页面了解算法和演示。

我们使用函数:cv.approxPolyDP (曲线, approxCurve, epsilon, closed)

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

尝试一下

5. 凸包

凸包看起来类似于轮廓近似,但事实并非如此(在某些情况下,两者可能会提供相同的结果)。在这里,cv.convexHull() 函数检查曲线的凸性缺陷并进行校正。一般来说,凸曲线是总是向外凸出或至少是平坦的曲线。如果向内凸出,则称为凸性缺陷。例如,检查下图中的手。红线显示手的凸包。双向箭头标记显示凸性缺陷,这些缺陷是凸包与轮廓的局部最大偏差。

image

我们使用函数:cv.convexHull (点, hull, clockwise = false, returnPoints = true)

参数
points输入 2D 点集。
hull输出凸包。
clockwise方向标志。如果为 true,则输出凸包将按顺时针方向定向。否则,它将按逆时针方向定向。假定的坐标系使其 X 轴指向右侧,Y 轴指向上方。
returnPoints操作标志。对于矩阵,当标志为 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 (点, line, distType, param, reps, aeps)

参数
points输入 2D 点集。
line输出直线参数。它应该是 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, color, thickness = 1, lineType = cv.LINE_8, shift = 0)

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

尝试一下