Opencv:基于Hu-moments(hu矩)的形状匹配

本文将按照以下目录展开介绍:

  1. 什么是图像矩;
  2. 如何计算图像矩:
  3. 什么是Hu矩;
  4. 如何利用Opencv计算一个图像Hu矩;
  5. 如何利用Hu-矩来寻找两个形状的相似性;

1. 什么是图像力矩

图像矩是图像像素灰度值的加权平均,下面通过一个简单的例子来说明。
假设有一个单通道的二值图像 I ,位置 (x,y) 出的灰度值是 I(x,y), I(x,y) 的取值是 0 或 1。最简单的一种力矩可以通过以下方程来定义:
在这里插入图片描述
上述方程图像矩是通过计算所有像素点灰度值之和,换句话说,所有像素灰度值的权重都为1,而并没有根据像素在图像中的位置来决定。对于一个二值图像,图像矩又可以通过以下两种不同的方式来描述:

  1. 白色区域(灰度值为255)的像素点的数目;
  2. 白色区域的面积;
    到目前为止,对图像矩的理解可能并没有那么深刻,下面是三幅二值图像(又可以称为三个Blob):(1) S (2) 旋转S (3) K
    在这里插入图片描述
    经过以上对二值图像矩的介绍,S与旋转S的图像矩应该是接近的,S与K的图像矩差异比较大。

2. 如何计算图像矩

2.1 raw moments

如下是一个更复杂的矩:
在这里插入图片描述
其中 i 和 j 是整数(不是上角标,而是作为幂次),这种矩通常被称为“raw moments(原始矩)” 用以与后文将要提到的“central moments(中心矩)” 进行区分。注意到以上矩的计算方式依赖于像素灰度值和像素在图像中的位置,所以直觉上能感觉出来这种矩捕捉到了某些形状的概念。

利用图像矩计算质心

以下公式用来计算质心:
在这里插入图片描述

2.2 Central moments

central moments”与raw moments” 非常类似,但在“central moments” 中我们会把质心从x, y 中提取出来,如以下公式:
在这里插入图片描述
以上“central moments” 具有平移不变性, 换句话说,不论Blob在二值图像中的什么位置,只要形状相同,“central moments” 就相同;

2.3 normalized central moments

按照下式更改方程,会给图像矩添加尺度不变性,以下方程又称为normalized central moments(归一化中心矩)
在这里插入图片描述

3. 什么是Hu矩

对于形状匹配来说,我们希望计算出来的矩具有平移不变性,旋转不变性,尺度不变性,Hu矩就可以满足这一要求;hu矩 是7个数字的组合,每个数字都是利用central moments计算得来,前6个被证明包含平移不变性,旋转不变性,尺度不变性和翻转不变性,第7个的符号与图像翻转有关。计算方式如下:
在这里插入图片描述

4. 如何利用Opencv计算一个图像Hu矩

Opencv中存在一个有效的函数来计算Hu矩,这个函数是HuMoments(), 下面一步一步的来看如何计算图像中存在的形状的hu矩。

4.1 将图像转换读取灰度图

Mat im = imread(filename,IMREAD_GRAYSCALE); 

4.2 利用阈值将图像二值化

threshold(im, im, 128, 255, THRESH_BINARY);

4.3 计算hu矩

Opencv有内置函数来计算Hu矩,利用central moment(中心矩)做输入

// 计算矩
Moments moments = moments(im, false);
 
// 计算hu矩
double huMoments[7];
HuMoments(moments, huMoments);

4.4 log转换
通过以上步骤计算得到的Hu矩值分布范围较大,例如第一幅图片中"K"的hu-矩:

h[0] = 0.00162663
h[1] = 3.11619e-07
h[2] = 3.61005e-10
h[3] = 1.44485e-10
h[4] = -2.55279e-20
h[5] = -7.57625e-14
h[6] = 2.09098e-20

对比发现h[0]和h[6]数量级相差很大,所以我们需要log转换将所有值分布到相同的范围里:
在这里插入图片描述
经过以上转换,所有值分布在一个可比的规模上:

H[0] = 2.78871
H[1] = 6.50638
H[2] = 9.44249
H[3] = 9.84018
H[4] = -19.593
H[5] = -13.1205
H[6] = 19.6797

log转换代码如下:


for(int i = 0; i < 7; i++)
{
  huMoments[i] = -1 * copysign(1.0, huMoments[i]) * log10(abs(huMoments[i]));  
}

5.利用Hu矩的形状匹配

正如前边提到的,所有的7个数字具有平移不变性,旋转不变性,尺度不变性,如果一个形状是另一个的镜像图片,那么他们的hu矩中第七个数字符号是相反的,我们看一个例子,如下图显示了6个图片和他们的Hu矩结果:
在这里插入图片描述

正如上图所示,图像K0.png是字母K; S0.png是字母S; 移动S形成S1.png; 添加尺度变化形成S2.png;添加旋转形成S3.png; 进一步翻转形成S4.png;
可以注意到,S0,S1,S2,S3和S4 的Hu矩在数值上都是相近的,S4 的H[6] 数值符号与其他的相反,同时我们还发现数值与K0的hu矩值有较大的差异;

5.1 利用matchShapes计算两个形状的差异

这一节介绍如何利用Hu矩寻找两个形状的差异。如果差异很小,说明两个形状在外观上相似;如果差异很大,说明两个形状在外观上相差大;Opencv提供了一个内置函数 matchShapes 来利用图像的Hu矩计算他们的差异性。

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);

有三种差异度量方式,通过第三个参数来控制,第二种方式结果略好。那么我们来看一下这三种度量方式是如何定义的, 定义 D(A,B) 是形状 AB之间的差异, 三种方式如下:

  1. CONTOURS_MATCH_I1
    在这里插入图片描述
  2. CONTOURS_MATCH_I2
    在这里插入图片描述
  3. CONTOURS_MATCH_I3
    在这里插入图片描述
    当我们计算S0, K0,S4之间的差异性,结果如下:(值越小说明二者的相似性越高)

Shape Distances Between ————————-
S0.png and S0.png : 0.0
S0.png and K0.png : 0.10783054664091285
S0.png and S4.png : 0.008484870268973932

5.1 自定义差异性测量

当然你也可以自己定义差异测量方式,比如利用欧几里得距离:
在这里插入图片描述
首先计算Hu矩的log转换,然后利用自己定义的方式来计算差异性。

  • 17
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值