akaze特征匹配怎么去掉不合适的点_基于Flann特征匹配和拉普拉斯掩模的图片相似度及清晰度评价...

最近在公司实习,做了一个项目,也是第一个我从头到尾自己负责的一个完整的项目吧,其实还是有一点小小的成就感的,因为毕竟是自己第一次成功的尝试。项目主要是做一个可以对图片清晰度和相似度进行评价的系统,可以用传统的CV算法来做,也可以利用基于孪生网络(Siamese network)的深度学习方法(后面会单独写一篇文章来介绍)。本篇文章主要分享一下自己在做这个项目的时候所使用过的几种传统CV算法。

图片清晰度

评价图片清晰度方面比较简单,这里我采用了拉普拉斯掩模的算法。

拉普拉斯掩模算法[1]

之所以拉普拉斯算法可以用于图片清晰度上面是基于类似于这样一个原理:在信号处理领域,会将图片通过傅里叶变换转换成高低频的分布,如果图片中有少量高频分布,该图片就可以被认为是模糊的。然而,区分高频量多少的具体阈值却是十分困难的,不恰当的阈值将会导致极差的结果。

在我引用的这篇博客中,作者想到了利用一个具体的浮点数来判断图片是否清晰,不过模糊清晰具体的数字界限不是固定的,需要通过大量的实验去确定。那么这个浮点数怎么来确定呢?这就用到了拉普拉斯方差

c70a85b6a20d49b7e3ef09b59015048f.png
图1 拉普拉斯掩模

将图片的某一通道(一般会先将图片灰度化)用上面的拉普拉斯掩模去做卷积运算,然后计算方差,如果某图片方差低于预先定义的阈值,那么该图片就可以被认为是模糊的。高于阈值,就不是模糊的。这种方法凑效的原因就在于拉普拉斯算子定义本身。它被用来测量图片的二阶导数,突出图片中强度快速变化的区域,和 Sobel 以及 Scharr 算子十分相似。并且,和以上算子一样,拉普拉斯算子也经常用于边缘检测。此外,此算法基于以下假设:如果图片具有较高方差,那么它就有较广的频响范围,代表着正常,聚焦准确的图片。但是如果图片具有有较小方差,那么它就有较窄的频响范围,意味着图片中的边缘数量很少。正如我们所知道的,图片越模糊,其边缘就越少。很显然,此算法的技巧在于设置合适的阈值。然而,阈值却十分依赖于所应用的领域。阈值太低会导致正常图片被误断为模糊图片,阈值太高会导致模糊图片被误判为正常图片

在python中拉普拉斯方差计算只需要一行代码:

cv2

图片相似度

我做的项目主要是根据客户提供的图片库,任意取出一张图片,可以从中检索出所有符合条件的相似图片。这里介绍几种关于图像相似度的算法:

哈希算法:[2]

平均哈希算法(ahash):

此算法是基于比较灰度图每个像素与平均值来实现的,最适用于缩略图,放大图搜索。

1.缩放图片:为了保留结构去掉细节,去除大小、横纵比的差异,把图片统一缩放到8*8,共64个像素的图片。

2.转化为灰度图:把缩放后的图片转化为256阶的灰度图。

附上灰度图相关算法(R = red, G = green, B = blue)

1.浮点算法:Gray=R*0.3+G*0.59+B*0.11

2.整数方法:Gray=(R*30+G*59+B*11)/100

3.移位方法:Gray =(R*76+G*151+B*28)>>8;

4.平均值法:Gray=(R+G+B)/3;

5.仅取绿色:Gray=G;

3.计算平均值: 计算进行灰度处理后图片的所有像素点的平均值。

4.比较像素灰度值:遍历灰度图片每一个像素,如果大于平均值记录为1,否则为0.

5.得到信息指纹:组合64个bit位,顺序随意保持一致性即可。

6.对比指纹:计算两幅图片的指纹,计算汉明距离(从一个指纹到另一个指纹需要变几次),汉明距离越大则说明图片越不一致,反之,汉明距离越小则说明图片越相似,当距离为0时,说明完全相同。(通常认为距离>10 就是两张完全不同的图片)

感知哈希算法(phash):

平均哈希算法过于严格,不够精确,更适合搜索缩略图,为了获得更精确的结果可以选择感知哈希算法,它采用的是DCT(离散余弦变换)来降低频率的方法

1.缩小图片:32 * 32是一个较好的大小,这样方便DCT计算

2.转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤)

3.计算DCT:DCT把图片分离成分率的集合

4.缩小DCT:DCT是32*32,保留左上角的8*8,这些代表的图片的最低频率

5.计算平均值:计算缩小DCT后的所有像素点的平均值。

6.进一步减小DCT:大于平均值记录为1,反之记录为0.

7.得到信息指纹:组合64个信息位,顺序随意保持一致性即可

8.对比指纹:计算两幅图片的指纹,计算汉明距离(从一个指纹到另一个指纹需要变几次),汉明距离越大则说明图片越不一致,反之,汉明距离越小则说明图片越相似,当距离为0时,说明完全相同。(通常认为距离>10 就是两张完全不同的图片)

差异哈希算法(dhash):

相比pHash,dHash的速度要快的多,相比aHash,dHash在效率几乎相同的情况下的效果要更好,它是基于渐变实现的。

1.缩小图片:收缩到9*8的大小,一遍它有72的像素点

2.转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤)

3.计算差异值:dHash算法工作在相邻像素之间,这样每行9个像素之间产生了8个不同的差异,一共8行,则产生了64个差异值

4.获得指纹:如果左边的像素比右边的更亮,则记录为1,否则为0.

需要说明的是这种指纹算法不仅可以应用于图片搜索,同样适用于其他多媒体形式。除此之外,图片搜索特征提取方法有很多,很多算法还有许多可以改进的地方,比如对于人物可以先进行人脸识别,再在面部区域进行局部的哈希,或者背景是纯色的可以先过滤剪裁等等,最后在搜索的结果中还可以根据颜色、风景、产品等进行过滤。

基于SIFT方法特征提取的Flann匹配器:[3][4]

1.SIFT特征提取:尺度空间的极值检测:尺度空间指一个变化尺度(σσ)的二维高斯函数G(x,y,σ)G(x,y,σ)与原图像I(x,y)I(x,y)卷积(即高斯模糊)后形成的空间,尺度不变特征应该既是空间域上又是尺度域上的局部极值。极值检测的大致原理是根据不同尺度下的高斯模糊化图像差异(Difference of Gaussians,DoG)寻找局部极值,这些找到的极值所对应的点被称为关键点或特征点。

2. 关键点定位:在不同尺寸空间下可能找出过多的关键点,有些关键点可能相对不易辨识或易受噪声干扰。该步借由关键点附近像素的信息、关键点的尺寸、关键点的主曲率来定位各个关键点,借此消除位于边上或是易受噪声干扰的关键点。

3. 方向定位:为了使描述符具有旋转不变性,需要利用图像的局部特征为给每一个关键点分配一个基准方向。通过计算关键点局部邻域的方向直方图,寻找直方图中最大值的方向作为关键点的主方向。

4. 关键点描述子:找到关键点的位置、尺寸并赋予关键点方向后,将可确保其移动、缩放、旋转的不变性。此外还需要为关键点建立一个描述子向量,使其在不同光线与视角下皆能保持其不变性。SIFT描述子是关键点邻域高斯图像梯度统计结果的一种表示,见下图。通过对关键点周围图像区域分块,计算块内梯度直方图,生成具有独特性的向量,这个向量是该区域图像信息的一种抽象,具有唯一性。Lowe在原论文中建议描述子使用在关键点尺度空间内4*4的窗口中计算的8个方向的梯度信息,共4*4*8=128维向量表征。

ab95b1601e13616d8040b508a5b9a704.png
图2 SIFT和SURF方法特征提取的差异

FLANN(Fast Library for Approximate Nearest Neighbors),利用近似k近邻算法去寻找一致性,用比值判别法(ratio test)删除离群点,这里使用过的kNN匹配的k值为2(在训练集中找两个点),第一个匹配的是最近邻,第二个匹配的是次近邻。直觉上,一个正确的匹配会更接近第一个邻居。换句话说,一个不正确的匹配,两个邻居的距离是相似的。因此,我们可以通过查看二者距离的不同来评判距匹配程度的好坏。比值检测认为第一个匹配和第二个匹配的比值小于一个给定的值(一般是0.5),这里是0.7:在复杂的环境中,FLANN算法不容易将对象混淆,而像素级算法则容易混淆。

上面的算法都有小编代码的实现,其中FLANN匹配的相似度算法结合了wxpython图形界面化,代码都在小编的GitHub主页上:

TKrobinpan/Ambiguity-and-Similarity-of-pictures​github.com
bfeda8d1a5fd3c5565fa6418807a3577.png

参考

  1. ^用 Opencv 和 Python 对汪星人做模糊检测 https://blog.csdn.net/iodjsvf8u1j7kyc/article/details/79136296
  2. ^相似图片搜索的三种哈希算法 https://blog.csdn.net/zmazon/article/details/8618775
  3. ^基于特征检测(SURF,SIFT方法)与特征匹配(Feature Matching)(FLANN方法) https://www.jianshu.com/p/1f6195352b26
  4. ^SIFT特征提取 https://blog.csdn.net/blateyang/article/details/76512398
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值