我们希望能用很少的几个特征代表一个图形,这些特征不因图形在图像中所在的位置、旋转角度、缩放比例的改变而改变,也不应受光照、噪点等影响。经过计算机视觉多年的发展,已经发现了很多这样的特征, 不变矩
就是其中一个。
统计学中的矩
图像的几何矩
将图像的像素坐标看作是二维随机变量,像素的灰度值看作是概率,就可以套用统计学中的矩作为图像的几何矩。
原点矩:\(M_{ij}=\sum_x \sum_y x^iy^jI(x,y)\)
中心矩:\(\mu_{ij}=\sum_x \sum_y (x-\hat x)^i(y-\hat y)^jI(x,y) \text ,其中(\hat x, \hat y)为图形的质心(重心)\)
- 零阶矩 \(M_{00}=\sum_x \sum_y I(x, y) \text {,其中I(x,y)表示在(x,y)处的像素灰度值}\) 零阶矩计算的是所有像素灰度的总和,类比统计学中的概率总和
- 一阶矩 \(\begin{cases} M_{10}=\sum_x \sum_y xI(x, y) \\ M{01}=\sum_x \sum_y yI(x, y) \end{cases}\) 一阶矩计算出图像横纵坐标的加权和,权值即为该坐标像素。若想将权值归一化到(0,1)的区间,则可以将每个像素灰度值除以灰度总和,这样一阶矩就类似统计学中的数学期望了,该期望值是横纵坐标轴的加权平均值。该坐标点即为图形的质心(重心)坐标: \(\begin{cases} xc=M{10} / M_{00} \\ yc=M{01} / M_{00} \end{cases}\)
- 二阶矩 \(\begin{cases} M_{20}=\sum_x \sum_y x^2I(x, y) \\ M{02}=\sum_x \sum_y y^2I(x, y) \\ M11=\sum_x \sum_y xyI(x,y) \end{cases}\) 类比上述统计学中的k阶原点矩
- 二阶中心矩 \(\begin{cases} \mu_{20}=\sum_x \sum_y (x-xc)^2I(x, y) \\ \mu{02}=\sum_x \sum_y (y-y_c)^2I(x, y) \end{cases}\) 即方差
Hu矩
中心距仅保证了平移不变性,若想要保证缩放不变性,则对中心矩归一化:
\(\mu{ij}=\frac {\mu{ij}}{\mu_{00}^\frac {i+j}{2}}\)
则 \(\mu_{ij}\) 就同时具有平移和缩放不变性,但仍没有旋转不变性。为了解决该问题,又创造了Hu矩
Hu矩利用二阶和三阶中心矩导出下面七个不变矩组,他们都能同时保证平移、缩放、旋转不变性:
OpenCV计算矩
函数 mouents()
用于计算几何矩(例如 \(m{10}, m_{00}\) 等,由此可计算出质心),函数 HuMouents()
用于计算Hu矩。以下为七个不变矩的实际效果(为了便于比较,结果都使用 log 输出):
类别 | logΦ1 | logΦ2 | logΦ3 | logΦ4 | logΦ5 | logΦ6 | logΦ7 |
---|---|---|---|---|---|---|---|
![]() |
-0.73284477 | -4.03663788 | -4.60583091 | -5.82204057 | -11.43743258 | -8.5494323 | -11.0731733 |
![]() |
-0.73314315 | -4.02402135 | -4.62038034 | -5.82720992 | -11.3825481 | -8.65752946 | -11.10418714 |
![]() |
-0.73229518 | -3.39709868 | -4.64708003 | -5.97302626 | -11.42148953 | -9.28521013 | -11.44641411 |
![]() |
-0.72623716 | -4.03247931 | -4.45534195 | -5.74960368 | -11.13747495 | -8.02235997 | -10.92001685 |
![]() |
-0.75198887 | -3.55789031 | -4.66384774 | -6.11429439 | -11.75662738 | -7.90211745 | -11.58441757 |
![]() |
-0.70095217 | -4.2838109 | -4.51830132 | -6.09603379 | -11.47543038 | -8.49974479 | -11.677337 |
![]() |
-0.77450821 | -2.85846763 | -3.42606589 | -5.49647798 | -10.05068259 | -6.98278071 | -10.18685455 |
![]() |
-0.74975294 | -2.59789974 | -3.01963955 | -4.70769731 | -8.6134227 | -6.04200389 | -8.9485131 |
![]() |
-0.72068034 | -3.11899114 | -4.68006236 | -4.26810178 | -9.02706987 | -6.01694837 | -8.81031275 |
可以直接使用 matchShapes()
方法来对不两个图形Hu矩的差值,根据该差值可以判断是不是同一个图形。差值越小则越接近。
附: