本文最后更新于:2024年5月7日 下午
一个跟轮廓相关的最常用到的功能是如何匹配多条轮廓。我们或许需要比较两条计算好的轮廓,或者比较一条轮廓和一个抽象模板。这两种情况都会在本文讨论。
矩
-
比较两条轮廓最简洁的方法之一是比较它们的轮廓矩。轮廓矩代表了一条轮廓、一幅图像、一组点集的某些高级特征。下面的所有讨论对轮廓、图像、点集都同样适用,简便起见,将它们统称为对象。矩的数值定义如下式:
$$
m_{p, q}=\sum_{i=1}^{N} I\left(x_{i}, y_{i}\right) x^{p} y^{q}
$$
在上式中, $ m_{p, q} $ 代表对象中所有像素的总和, 其中每个像素 $ x, y $ 的像素值都乘以因子 $ x^{p} y^{q} $ , 在 $ m_{00} $ 时, 这个因子等于 1 。.
- 因此若图像为二值图(例如,所有像素都等于0或者1),则 $ m_{00} $ 代表图像上所有值非零的区域。当处理轮廓时,结果是轮廓的长度。
- 将$m_{10}$和$m_{01}$相加再除以mo,能得到整个对象的平均x值和y值。
cv2.moments
计算多边形或光栅化形状的所有矩,最高可达三阶。
- 仅适用于来自 Python 绑定的轮廓矩计算: 注意,输入数组的 numpy 类型应该是
np.int32
或np.float32
。 - 函数使用
1 |
|
- retval 包含多组矩:
矩名称 | 含义 |
---|---|
m00 | 零阶矩 |
m10, m01 | 一阶矩 |
m20, m11, m02 | 二阶矩 |
m30, m12, m21, m03 | 三阶矩 |
mu20, mu11, mu02 | 二阶中心距 |
mu30, mu21, mu12, mu03 | 三阶中心距 |
nu20, nu11, nu02 | 二阶归一化中心矩 |
nu30, nu21, nu12, nu03 | 三阶归一化中心矩 |
- 示例代码
1 |
|
-
计算第二个 Hu 不变矩测试归一化中心矩:
-
公式为:
$$ h_2=(v_{20}+v_{02})^2+4v_{11}^2 $$ -
示例代码:
1 |
|
Hu 矩
cv2.HuMoments
函数用于计算 Hu 矩:
- 函数使用
1 |
|
- 示例代码
1 |
|
使用Hu矩进行匹配
- 我们想要使用Hu矩比较两个物体,并判定它们是否相似。对“相似”的定义可能有很多。为了使比较过程变得简单,OpenCV的函数
cv2.matchShapes
允许我们简单提供两个物体,然后计算它们的矩,并根据我们提供的标准进行比较。
cv2.matchShapes
该函数比较两个形状,所有三个实现的方法都使用 Hu 不变量。
- 函数使用
1 |
|
-
method: ShapeMatchModes
$A, B $分别表示两个输入的物体轮廓
$$ \begin{array}{c} m_{i}^{A}=\operatorname{sign}\left(h_{i}^{A}\right) \cdot \log h_{i}^{A} \\ m_{i}^{B}=\operatorname{sign}\left(h_{i}^{B}\right) \cdot \log h_{i}^{B} \end{array} $$其中 $ h_{i}^{A}, h_{i}^{B} $ 为 $A,B$ 的 Hu 不变矩
参数 含义 cv2.CONTOURS_MATCH_I1 $ I_{1}(A, B)=\sum_ {i = 1 \ldots . } \left | \frac{1} {m_{i}^{A}}-\frac{1}{m_{i}^{B}}\right|$ cv2.CONTOURS_MATCH_I2 $ I_{2}(A, B)= \sum_{ i=1 \ldots . } \left | m_{i} ^ {A}-m_{i}^{B}\right|$ cv2.CONTOURS_MATCH_I3 $ I_{3}(A, B)=\max _{i=1 \ldots 7} \frac{\left|m_{i}^{A}-m_{i}^{B}\right|}{\left|m_{i}^{A}\right|} $ -
示例代码 1
1 |
|
- matchShapes 的结果值越小说明两个形状越接近,形状接近的图形匹配结果更接近 0
- 示例代码 2
1 |
|
- 输出结果
1 |
|
缩放平移不改变形状匹配结果
利用形状场景方法比较轮廓
OpenCV 努力提供比矩匹配更好的形状匹配算法
https://docs.opencv.org/4.5.5/d1/d85/group__shape.html#ga1d058c5d00f6292da61422af2f3f4adc
- 在 OpenCV 4.5.5 中还没有实现,有传说在 3.5 的版本中有相关函数
源码
https://github.com/zywvvd/Python_Practise/tree/master/OpenCV/Chapter 14
参考资料
-
《学习OpenCV》 第十四章
文章链接:
https://www.zywvvd.com/notes/study/image-processing/opencv/opencv-contours-match/contours-match/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付