【局部特征】ASIFT

      因为相机正面白摄物体时,相机的光轴方向可能发生变化,带来扭曲。而SIFT算法虽具备彻底的尺度不变性,但不具备彻底的仿射不变性,对拍摄角度发生大角度空间变化的图像特征提取有必定的局限性。ASift经过模拟经度与纬度实现彻底的仿射不变,而后用SIFT算法把模拟图像进行比较,最后实现特征匹配。python

ASIFT算法的具体步骤以下:git

1.选取采样参数,模拟不一样经度与纬度的图像。github

2.计算模拟图像的特征。算法

3.结合全部的模拟图像的特征,进行特征匹配。多线程

注意:ASIFT提供的一种框架,其核心思想是模拟不一样的经度与纬度的图像,具体模拟图像的特征提取和匹配,可选择SIFT、SURF等特征。框架

ASIFT算法代码资源:异步

http://www.ipol.im/pub/art/2011/my-asift/测试

https://github.com/Itseez/opencv/blob/master/samples/python2/asift.pyspa

OpenCV只提供python实现的asift,若是须要在C++中使用asift,主要有两种方法可参考。线程

1.利用做者提供的C++代码,具体使用方法可参考做者提供的文档。

2.将asift.py翻译成C++代码。

asift.py代码相对清晰,转换成基于OpenCV的C++代码比较容易,我主要参用方法2,实现ASIFT算法。

遇到的问题:

1.处理分辨率较大图片时,出现OpenCV Error: Insufficient memory的错误。

  经分析,计算过程须要保存多张模拟图片的特征点和特征描述子,须要大量内存,致使OpenCV分配内存时,没有连续可用的内存块,从而出现OpenCV Error: Insufficient memory的错误。

  解决方法:下降待处理图片的分辨率,并计算高分辨率到低分辨率转换的单应性矩阵scaleH。利用ASift算法计算低分辨率图片的匹配的单应性矩阵matchH。最终待处理图片的单应矩阵H=matchH*scaleH。

2.计算复杂度问题。

  因为须要处理多幅模拟图片的特征点检测,计算复杂度高。目前,主要有两种思路:1).下降分辨率,减小计算量。2).利用硬件特性进行硬件计算。

ASift做者在文中提到的Two-Resolution Procedure.

(1).采用系数K*K二次采样查询图片u和待搜索图片v。u = SkGku,v=SkGkv,Gk是反走样高斯离散滤波器,SK为K*K二次采样。

(2).低分辨率下的ASIFT算法:对查询图片u和搜索图片应用ASIFT算法;

(3).肯定u和v中可能产最多匹配对的M种仿射变换;

(4).高分辨率下的ASIFT算法:在原始图像u和v上使用ASIFT算法,但模拟倾科时只使用这M种仿射变换。

经实验测试,发现Two-Resolution Procedure虽然能够在必定下降复杂度,但其对匹配精度会有必定的影响,对于匹配精度要求高的应用不太合适

Asift.py中,利用线程池加速多幅图像的特征点检测,使得多幅图像的特征点检测同时进行。

结合多线程的思想,我利用每一个线程,计算每幅图像的特征点的检测,结果遇到内存不足的问题。

主要缘由:特征点检测过程须要内存空间存储部分中间结果,当多线程同时计算时,所需内存增大,出现内存不足的问题。

解决方法:能够根据待处理图片的分辨率大小和系统提供内存资源的多少,自适应肯定多线程的数目。

利用GPU加速ASIFT计算,具体步骤以下:

(1).将待处理图片传输到GPU端。

(2).将待处理图片模拟变换,获得模拟图片,AffineImage_Kernel。

(3).计算模拟图片的特征点,KeyPointsDetect_Kernel。

(4).将计算所得的特征点数据传输到CPU端。

(5).循环处理(2)、(3)、(4)步骤,直到全部模拟变换处理完。

(6).在CPU端完成特征点匹配计算。

注意:(4)与(5)能够异步执行,重叠计算与特征点数据传输的时间。

基于GPU特征点计算主要参考:

SiftGPU: http://cs.unc.edu/~ccwu/siftgpu/

CudaSift: https://github.com/Celebrandil/CudaSift

注意:经测试,发现SiftGPU和CudaSift检测出的特征点数目与OpenCV的SiftFeatureDetector检测出特征点数目差别较大。

相关文章
相关标签/搜索