zoukankan      html  css  js  c++  java
  • 一篇看懂SIFT算法

      现在在做的一个项目,就是把SIFT算法弄到FPGA板子上加速。用的板子V7 690,大概43万的LUT和86万FF,最后差不多用到了八成,时序挺紧张的了。频率跑到了125Mhz,瓶颈主要在浮点核吃资源太多。速度是70ms实现sift特征向量生成,FPGA实现的部分大概是30ms左右,图像输入是320x256。当然不是所有的工作都在FPGA上做的。在FPGA上的是四个模块,包括高斯滤波,高斯差分,极值点检测,梯度计算,其他的工作是在DSP上做的。我做的是高斯滤波和梯度计算两个部分。

      首先是为什么是SIFT,SIFT是做特征提取的。而要做的特征提取是希望效果稳定,SIFT的提取出来的特征对于尺度变化,平移,缩放,旋转和倾斜以及光照度的变化都有着很好的适应性。本身SIFT的全称就是Scale Ivariant Feature Transform。尺度不变特征变换。

      什么是尺度,尺度很容易理解,先不要考虑尺度空间。我们可以简单地对比地图的缩放。同一个地方在不同比例尺下的样式截然不同。2公里保留了更多的细节,而20公里仅剩下轮廓。这两张图片非常类似人眼的观察。我们可以说,这两张图就是图中这条河在不同尺度下的两个点。那么我们如何能模拟人眼中这种变化呢?前辈们已经证明了,通过高斯滤波能达到这个目的,而且只有高斯滤波可以。也就是说,高斯滤波除掉的细节和人眼中物体变远所丢失的细节是一样的。

      那么总结一下,特征是有尺度的,20公里的图片中的特征不一定就能反映到2公里,反之亦然。所以我们做两个图像的匹配的时候,我们需要把他们放到相近的尺度。

     这个是2公里比例尺这个是20公里比例尺

      除此之外,我们还需要把图像降采样,也就是缩分辨率。为什么呢,因为特征提取出来,本质上是用来做匹配或者识别的,对于计算机来说,我们无法确定输入图像到底是什么尺寸。那我们要对两幅图像做匹配,就必须把两幅图像放到相似的分辨率和尺度,那么理论上来讲,我们要做两个工作,第一个就是得到一系列不同尺度的图像,第二个是得到一系列不同分辨率的图像。而尺度和分辨率又有一定的相关性,因为对于同一个成像系统,当它对某个区域成像分辨率降低了,也就意味着它们的尺度变大了/变远了。

      降采样需要滤波,原理Nyquist定律。

      而且,尺度只能往上走,变得更模糊,而分辨率只能往下走,变得更低,这两个是统一的。那么也就是说,假如我们已经有了一辆坦克图像,如果我们拍到另一个坦克的照片,即使这个照片分辨率更低,我们离它更远,那么我们识别出的概率依旧很大。但是我们如果只拍到一个炮塔,那么不论我们如何降分辨率,增加尺度,它能匹配的也只能是库中的一部分,成功的概率就低一些,取决于我们的命中阈值设定。

      如果做了这两步,我们的特征提取就对远近有了很强的适应。那么对于其他例如光照和旋转,如何做呢?

      光照相对简单,归一化可以做出一定程度的光照不变性,而且这一步非常适合在预处理的时候做,实际上我们也是这么干的。而旋转不变性依赖于使用图像内像素本身的相对位置信息,这里用的是梯度模和梯度角。

      那么还剩下两个部分,一个是DOG,为什么要做差分,另一个是极值点究竟如何确定,在一个分辨率上确定的极值点如何定位到图片上。

      实际上,效果最好的是LOG,也就是对图像求二阶导,但是计算效率太低,因此我们用DOG代替LOG,DOG是LOG的一个很好的近似。

       那么我们要做的就是,先对原始图像做高斯滤波,做几次之后选其中的一张作为降采样的输入(第一组的第0层是第0组的倒数第三张降采样得到的),降采样的结果就是下一级的第一张,然后再高斯滤波几次。重复以上步骤,就可以得到下图的结果。

      

       可以发现,每一内部组又有6层,每组的分辨率不同,每层的尺度不同,也就是卷积核的σ不同,组内上一层是下一层的K倍。而上一组对应层是下一组的2倍。至此我们就得到了分辨率和尺度都不一样的一组数据集。之后我们在同分辨率的组内做差分处理,得到差分的金字塔,这个金字塔组数相同而组内层数少了1。这个DOG金字塔就是做极值点检测的输入。具体来说,我们在组内做极值点检测,一次选相邻三层,以中间层的像素点为基准,它上下左右各有26个点,遍历看它是不是极大或者极小值点。也就是说,每组的最上层和最下层其实没做检测。

      再讲讲这个金字塔应该是几组几层,我们做的是4组6层,输入之前双线性插值升采样一波,图像尺寸翻倍,面积X4。

       o是组数,向下取整,xy是图像的长和宽。层数就是6,s=3。

      这里其实不太对,双线性插值类似低通滤波,高频信息直接被干掉了。

      极值点找到之后使用泰勒进行插值拟合。这部分由dsp完成,将极值点转化为特征点。

      之后要把特征点周围的所有像素点的梯度算出来,至此,FPGA干的活就介绍完毕了。

      算出来之后根据梯度角进行分类,梯度角从0到360,每10度一组,然后把同组的梯度模相加求和。最大的那一组就是特征点的主方向,其他组的和如果超过了最大组的80%,则记录为辅方向。那么现在我们描述的特征点就变成了(x,y,σ,主方向,辅方向1,...,辅方向n)

      

       

     

  • 相关阅读:
    洛谷2444(Trie图上dfs判环)
    【做题】Codeforces Round #453 (Div. 1) D. Weighting a Tree——拆环
    【做题】POJ3469 Dual Core CPU——第一道网络流
    【做题】atc_cf17-final_E
    【做题】spoj4060 A game with probability——dp
    Matlab AlexNet 识别花
    minutia cylinder code MCC lSSR 匹配算法
    Gabor filter for image processing and computer vision
    MATLAB 去掉数组里面不要的元素
    NBIS指纹特征提取与匹配软件使用
  • 原文地址:https://www.cnblogs.com/aliothx/p/13489087.html
Copyright © 2011-2022 走看看