ASIFT算法:超越SIFT的全仿射不变特征匹配

需积分: 10 7 下载量 159 浏览量 更新于2024-07-21 收藏 8.58MB PDF 举报
本文档介绍了一种名为ASIFT (Affine Scale-Invariant Feature Transform) 的算法,它是SIFT (Scale-Invariant Feature Transform) 算法的一种改进版本,旨在解决在物体识别问题中面对的全仿射不变性问题。SIFT算法原本着重于尺度、旋转和位移不变性,但ASIFT在此基础上进一步扩展,考虑了图像在不同相机位置下由于物体边界平滑或分段光滑引起的局部仿射变形。 ASIFT算法的设计背景是基于这样一个事实:当物体的边界是平滑的或由多个平滑部分组成时,其拍摄的图像在相机位置变化时会经历平滑的明显变形,这些变形可以通过局部仿射变换来近似。因此,将固态对象识别问题转化为在仿射变换下的图像局部特征计算具有重要意义。 文章指出,ASIFT算法的主要改进在于它模拟了一个“完全仿射不变”的特性,这使得它在处理如缩放、旋转以及更复杂的仿射变换(包括扭曲)时更加有效和稳定。相比于原始的SIFT,ASIFT能够在各种情况下提供更为准确和鲁棒的特征匹配,这对于计算机视觉中的目标检测、物体识别、图像配准等任务来说是一大进步。 该算法发表于2011年2月24日的《在线图像处理》(Image Processing Online),并经过了提交、接受过程,遵循了ISSN 2105-1232的期刊标准。作者Guoshen Yu和Jean-Michel Morel分别来自法国的CMLA(ENSECachan)和CMAP(École Polytechnique),他们通过在线提供了补充材料、软件、数据集和在线演示,方便读者深入理解和使用ASIFT。 截至2014年7月1日,ASIFT算法已经发展到了v0.5版本,并被归类为IPOL(International Journal of Computer Vision and Image Processing Online)文章。ASIFT作为一种增强的图像特征提取工具,其核心优势在于能够提高在实际应用中对仿射变化的鲁棒性和准确性,为图像处理领域的研究者和实践者提供了强大的技术支撑。
2016-10-11 上传
OpenCV小项目 这是一个个人在使用OpenCV过程中写的一些小项目,以及一些非常有用的OpenCV代码,有些代码是对某论文中的部分实现。 注意:代码是在Xcode里写的,如果要在win下测试,遇到问题自己修改。 opencv-rootsift-py 用python和OpenCV写的一个rootsift实现,其中RootSIFT部分的代码参照Implementing RootSIFT in Python and OpenCV这篇文章所写,通过这个你可以了解Three things everyone should know to improve object retrieval这篇文章中RootSIFT是怎么实现的。 sift(asift)-match-with-ransac-cpp 用C++和OpenCV写的一个图像匹配实现,里面包含了采用1NN匹配可视化、1NN匹配后经RANSAC剔除错配点可视化、1NN/2NN<0.8匹配可视化、1NN/2NN<0.8经 RANSAC剔除错配点可视化四个过程,其中1NN/2NN<0.8匹配过程是Lowe的Raw feature match,具体可以阅读Lowe的Distinctive image features from scale-invariant keypoints这篇文章。这个对图像检索重排非常有用。另外里面还有用OpenCV写的ASIFT,这部分来源于OPENCV ASIFT C++ IMPLEMENTATION,ASIFT还可以到官网页面下载,ASIFT提取的关键点 比SIFT要多得多,速度非常慢,不推荐在对要求实时性的应用中使用。 更多详细的分析可以阅读博文SIFT(ASIFT) Matching with RANSAC。 有用链接 OpenCV3.0文档 // 测试sparse unsigned int centersNum = 10; vector descrNums; descrNums.push_back(8); descrNums.push_back(12); //unsigned int T[] = {1, 2, 1, 3, 2, 5, 4, 3, 10, 5; 4, 2, 6, 5, 2, 5, 4, 6, 2, 4}; unsigned int T[] = {1, 2, 1, 3, 2, 5, 4, 3, 10, 5, 4, 2, 6, 5, 2, 5, 4, 6, 2, 4}; sp_mat Hist(descrNums.size(), centersNum); static long int count = 0; for (int i = 0; i < descrNums.size(); i++){ unsigned int* desrcElementsTmp = new unsigned int[descrNums[i]]; memcpy(desrcElementsTmp, T + count, descrNums[i] * sizeof(T[0])); //cout << desrcElementsTmp[0] << '\t' << desrcElementsTmp[1] << '\t' << desrcElementsTmp[2] << '\t' << desrcElementsTmp[3] << '\t' << desrcElementsTmp[4] << '\t' <<endl; //cout << desrcElementsTmp[5] << '\t' << desrcElementsTmp[6] << '\t' << desrcElementsTmp[7] << '\t' << desrcElementsTmp[8] << '\t' << desrcElementsTmp[9] << '\t' << desrcElementsTmp[10] << '\t' <<endl; //cout << endl; sp_mat X(1, centersNum); X.zeros(); for (int j = 0; j < descrNums[i]; j++){ X(0, desrcElementsTmp[j]-1) += 1; } X.print("X:"); X = X/norm(X, 2); Hist.row(i) = X; count = count + descrNums[i]; delete desrcElementsTmp; } //Hist.print("Hist:");