前阵子做图像搜索功能, 对比过一些搜索算法, 发现 sift 比较能满足我的需要, 它在图像旋转, 比例缩放, 图像扭曲的情况下也能有很好的识别效果, 在网上找了一些资料, 有些介绍了算法的细节, 有些做了对比评测
www.cscjournals.org/csc/manuscript/Journals/IJIP/volume3/Issue4/IJIP-51.pdf
2013计算机视觉代码合集 - Note of Transposition - 博客频道 - CSDN.NET
Computer Vision Algorithm Implementations
ImageAnalyzer | NeoTOS - Torben Schinke
OpenSIFT: An Open-Source SIFT Library
VLFeat(1)——SIFT图像特征提取(VC++实现)_席思丝萌_新浪博客
特征提取步骤 SIFT,PCA-SIFT,GLOH,SURF - 研发管理
原理就不扯了, 网上找来一个老外的代码, 按需要改造了一下, 封装了一个组件, 方便使用.
组件地址: https://github.com/myshzzx/mlib/tree/master/imagesearch
实际使用是这样的, 首先对图像进行预处理(比如缩小图像, 以减少无关的细节干扰), 然后对图像生成 SIFT 特征值. 图像搜索即是在大规模样本特征值里寻找与目标特征值最相近的特征值.
一般大小的图片可以计算出 10^2 ~ 10^3 数量级的特征值, 每个特征值是一个 float[128], 即一个 128 维浮点向量, 而图像搜索就是计算向量的欧氏距离, 找距离最小的样本向量, 这无疑是海量的计算. 一个比较好的做法是利用向量的空间信息构建k-d树, 即k维向量树, 这里 k=128, 查找的时候利用空间信息优先查找可能性大的分支, 搜索时间 T(n) = θ(log(n)).
我尝试用GPU加速来加快搜索, 用到 aparapi, 无奈它只支持基本类型的运算, 无法处理 Java 对象, 就是说k-d树没法用了, 只能用数组组织特征值, GPU处理欧氏距离的计算, 由于计算粒度小, 数据交互量大, 用这种方式反而可能比用CPU还慢.
这个组件比较适合样本图像差距较大的情况, 由于每个特征值的匹配查找只找出最接近的那个, 如果样本库里有多个与目标图像接近的图像, 那么最接近的那个会被找到, 而不那么接近的其他图像将会被它 "掩盖". 如果有这样的情况, 那么需要修改搜索代码.
下面贴一段示例代码演示一下它的用法.
public class SiftHelperTest { private static final Logger log = LoggerFactory.getLogger(SiftHelperTest.class); private static String[] dirs = new String[]{ "E:\\project\\texture\\picsRep\\sample" }; private static File resultDir = new File("l:/result"); public static void main(String[] args) throws IOException, InterruptedException { SiftHelper.FeaMgrType feaMgrType = SiftHelper.FeaMgrType.KDTree; final SiftHelper<String> analyzer = new SiftHelper<>(String.class, feaMgrType); // 准备预处理器 ImgPreProc samplePreProc = genImgPreProc(180); ImgPreProc testPreProc = genImgPreProc(150); analyzer.setImgPreProc(samplePreProc); analyzer.setMinMatchCount(2); // 准备样本库 final ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); for (String dir : dirs) FileUtil.recurDir(new File(dir), null, new FileUtil.FileTask() { @Override public void handle(final File f) { exec.submit(() -> { try { analyzer.bindImage(f.getName(), ImageIO.read(f)); } catch (Exception e) { e.printStackTrace(); } }); } }); exec.shutdown(); exec.awaitTermination(1, TimeUnit.DAYS); // 设置搜索超时, 即给定一个特征值的搜索超时, 设置一个合适的值可以获得很好的 搜索效果/搜索耗时 比. analyzer.getFeatureManager().setEachFeatureTimeout(3000); System.out.println("ready to search."); BufferedReader s = new BufferedReader(new InputStreamReader(System.in)); String file; while ((file = s.readLine()) != null) { if ((file = file.trim()).length() < 1) continue; // 执行搜索 searchImg(analyzer, file, testPreProc, dirs[0], resultDir); } } static void searchImg(SiftHelper<String> analyzer, String file, ImgPreProc preProc, String sampleDir, File resultDir) { try { List<ImageFeature> features = preProc.process(ImageIO.read(new File(file))); List<ImageAnalyzerResult<String>> res = analyzer.findImage(features); System.out.println(file + " Results: " + res.size()); int i = 1; if (resultDir.exists()) for (File child : resultDir.listFiles()) if (child.isFile()) child.delete(); for (ImageAnalyzerResult<String> result : res) { System.out.println(result); if (resultDir.exists()) { String dir = sampleDir + "/" + result.getUserObj(); Files.copy(Paths.get(dir), Paths.get(resultDir.getPath() + "/" + (i++) + " " + result.getUserObj())); } } System.out.println(); } catch (Exception e) { log.error("searchImg failed: " + file, e); } System.gc(); } static ImgPreProc genImgPreProc(int scaleLimit) { GrayScaleLimit preProc = new GrayScaleLimit(); ImageFeatureExtractor sift = new JavaSIFT(); preProc.setFe(sift); preProc.setScaleLimit(scaleLimit); return preProc; } }
相关推荐
• SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化 保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳 定性。 • 独特性(Distinctiveness)好,信息量丰富,适用于在海量特征 数据库中进行快速、...
SIFT算法基于图像特征尺度选择的思想,建立图像的多尺度空间,在不同尺度下检测到同一个特征点,确定特征点位置的同时确定其所在尺度,以达到尺度抗缩放的目的,剔出一些对比度较低的点以及边缘响应点,并提取旋转...
基于SIFT算法的图像拼接matlab代码,里面是一个可视化GUI,可以直接通过运行GUI-main找到特征值和进行图片拼接,也有具体实现代码,亲测有用,非常具体
SIFT算法的MATLAB源码,不使用sift_win32,根据论文一步一步编写,对于学习理解SIFT算法有重要意义。建议单步执行学习。
为了解决分布式的尺度不变特征转换(Scale-Invariant Feature Transform,SIFT)算法效率低和图像特征提取粗糙问题,提出一种基于深度学习的SIFT图像检索算法.算法思想:在Spark平台上,利用深度卷积神经网络...
基于SIFT算法的局部特征点人脸识别图像处理技术.pdf
实现了SIFT算法,实现了SAR与光学图像的自动配准,相比于手动方法更加智能化,去除了认为选择配准点的非鲁棒因素,配准精度能达到一个像素以内。
在对sift算法有了初步的了解后,有人表示,是否能用c语言实现sift算法,同时,尽量不用到opencv,gsl等第三方库之类的东西。而且,Rob Hess维护的sift 库,也不好懂,有的人根本搞不懂是怎么一回事。 那么本文,...
基于无监督学习,无需训练数据, 使用SIFT算法提取图像特征,再使用KMeans聚类算法进行图像分类。 对源代码进行了优化,实现了对应图片自动分类到各自文件夹功能,并且优化了分类准确率。 设计思路: 1)首先编写...
用c++编写的sift算法实现,图像处理领域的经典算法,下载运行需要导入opencv库。 SIFT (Scale-invariant feature transform),尺度不变特征转换,是一种图像局部特征提取算法,它通过在不同的尺度空间中寻找极值点...
用matlab实现sift算法的图像拼接
基于opencv的图像匹配算法实现,主要包含了sift的实现,以及已知物体的识别
基于内容的图像检索和Sift算法的应用的硕士毕业论文
a) SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性。 b) 独特性(Distinctiveness)好,信息量丰富,适用于在海量特征数据库中进行快速、...
sift算法论文图像配准,基于改进的sift算法,参考文献
包括特征点的选取 描述子的建立 和特征点的匹配
采用Harris 角点检测算法进行图像特征检测, 采用Sift 算法中的特征描述方法进行图像特征描 述, 之后将图像特征点划分为多对多匹配对, 根据特征描述值的支持强度不同建立精确的一对一匹配关系. 该算法有效地避免了...
opencv实现的SIFT算法源码,包含图像的SIFT特征提取算法,以及图像之间的基于SIFT特征的匹配算法
SIFT和旋转不变LBP相结合的图像匹配算法论文 IFT算法是性能最好、应用最广泛的基于局部特征的图像匹配算法,但其计算复杂度高.为此,提出一种 SIFT和旋转不变LBP相结合的图像匹配算法,以提高SIFT算法的速度.首先...
SIFT算法小结,word文档,SIFT算法是一种提取局部特征的算法,在尺度空间寻找极值点,提取位置,尺度,旋转不变量。