基于Hu距的匹配方式--OpenCV

  1. 什么是图像距?
  2. 如何计算图像距
  3. 什么是图像的Hu不变距
  4. 使用OpenCV计算Hu距
  5. 计算相似两幅图

1.什么是图像距?

图像矩是图像像素强度的加权平均值。 让我们选择一个简单的例子来理解。

为简单起见,让我们考虑单通道二进制图像I.位置(x,y)处的像素强度由I(x,y)给出。 注意二值图像I(x,y)可以取值0或1。

我们可以定义的最简单的距:

                                                                      

我们在上面的等式中所做的就是计算所有像素强度的总和。 换句话说,所有像素强度仅基于它们的强度加权,而不是基于它们在图像中的位置。

对于二值图像,可以以几种不同的方式解释上述Hu

  • 它是白色像素的数量(即强度= 1)。
  • 它是图像中白色区域的面积。

到目前为止,您可能不会对图像时刻留下深刻印象,但这里有一些有趣的东西。 图1包含三个二值图像 -  S(S0.png),旋转S(S5.png)和K(K0.png)。

S与旋转S的Hu距比较接近,与K的Hu距大不相同

对于两个相同的形状,上面的图像时刻必然是相同的,但它不是一个充分的条件。

2.如何计算图像的距

下面是一个更为复杂的距:

i,j是常数(int),

这些距通常被称为原始距,以区别于本文后面提到的中心距。

请注意,上述距取决于像素的强度及其在图像中的位置。 如此直观地说,这些距正在捕捉一些形状的概念。

质心--图像的距

质心计算:

中心距-图像的距

请注意,上述中心距是平移不变的。 换句话说,无论图像中的斑点在哪里,如果形状相同,则矩将是相同的。

如果我们还能让这个距具有尺度不变,那会不会很酷? 那么,为此,我们需要标准化的中心矩,如下所示。

Central moments are translations invariant, and normalized central moments are both translation and scale invariant.

3. Hu距

中心距是平移不变的。 但这还不足以进行形状匹配。 我们想要计算对平移,缩放和旋转不变的矩,如下图所示。

幸运的是,我们实际上可以计算出这样的距,他们被称为Hu不变距。

7个Hu不变距计算如下:

4. 在OpenCV中计算Hu不变距

1)读入图

2)二值化

3)计算Hu不变距

4. Log转化

K的7维Hu不变距

Python

# Log scale hu moments
for i in range(0,7):
  huMoments[i] = -1* copysign(1.0, huMoments[i]) * log10(abs(huMoments[i])))

C++

// Log scale hu moments
for(int i = 0; i < 7; i++)
{
  huMoments[i] = -1 * copysign(1.0, huMoments[i]) * log10(abs(huMoments[i]));  

5. 基于Hu不变距的形状匹配

计算Hu距:

如图所见,图像K0.png只是字母K,S0.png是字母S.接下来,我们在S1.png中移动字母S,并在S2.png中移动+缩放。 我们添加了一些旋转来制作S3.png并进一步翻转图像以制作S4.png。

注意,S0,S1,S2,S3和S4的所有Hu矩在值上彼此接近,除了翻转S4的最后Hu矩的符号。 另外,请注意它们与K0非常不同。

5.1 匹配形状的距离

在本节中,我们将学习如何使用Hu Moments来找到两个形状之间的距离。 如果距离小,则形状在外观上接近,并且如果距离大,则形状在外观上更加分开。

OpenCV提供了一个易于使用的名为matchShapes的实用程序函数,它接收两个图像(或轮廓)并使用Hu Moments找到它们之间的距离。 所以,你不必明确计算胡时刻。 只需将图像二值化并使用matchShapes。

用法如下所示。

Python

d1 = cv2.matchShapes(im1,im2,cv2.CONTOURS_MATCH_I1,0)
d2 = cv2.matchShapes(im1,im2,cv2.CONTOURS_MATCH_I2,0)
d3 = cv2.matchShapes(im1,im2,cv2.CONTOURS_MATCH_I3,0)

C++

double d1 = matchShapes(im1, im2, CONTOURS_MATCH_I1, 0);
double d2 = matchShapes(im1, im2, CONTOURS_MATCH_I2, 0);
double d3 = matchShapes(im1, im2, CONTOURS_MATCH_I3, 0);

Note:  可以通过第三个参数使用三种距离 ( CONTOURS_MATCH_I1, CONTOURS_MATCH_I2 or CONTOURS_MATCH_I3).

让我们看看如何定义这三个距离。

令D(A,B)为形状A和B之间的距离,并且为形状A和B的对数变换的Hu矩。定义对应于三种情况的距离 如

5.2 自定义距离

如果您想在两个形状之间定义自己的自定义距离测量,则可以轻松完成。 例如,您可能想要使用由给定的Hu矩之间的欧几里德距离

首先,如前一节所述,计算对数变换的Hu矩,然后自己计算距离,而不是使用matchShapes。

完整代码链接

猜你喜欢

转载自blog.csdn.net/red_ear/article/details/86165142