前阵子做图像搜索功能, 对比过一些搜索算法, 发现 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算法及过程详解 SIFT(Scale-Invariant Feature Transform)是一种电脑视觉算法,用于侦测与描述影像中的局部性特征。该算法由 David Lowe 于 1999 年提出,并于 2004 年完善总结。SIFT 算法的应用范围包含物体...
CUDA是NVIDIA公司推出的一种并行计算平台和编程模型,主要应用于高...此外,对于想要深入研究计算机视觉或图像处理的开发者来说,这是一个很好的实践案例,可以帮助他们理解SIFT算法的工作原理及其在GPU上的实现细节。
由David Lowe在1999年提出,SIFT算法能够提取出图像中的局部特征,这些特征对图像的尺度、旋转和亮度变化具有不变性,从而在不同条件下匹配图像非常有效。 **SIFT算法主要包括以下几个步骤:** 1. **尺度空间极值...
这种方法充分利用了Matlab快速易用的特点以及COM组件的灵活性,可以方便地将SIFT算法集成到现有的图像处理系统中。Matlab推出的Combuilder工具可以将用Matlab编写的程序封装成COM组件,使得其他支持.NET框架的语言...
10. **特征提取**:如角点检测(Harris角点、Shi-Tomasi角点)、SIFT(尺度不变特征变换)、SURF(加速稳健特征)等,这些特征对图像的旋转、缩放和光照变化具有鲁棒性,适合于图像匹配和识别。 在实际项目中,这些...
在Java中实现SIFT算法可以为那些需要在Java平台上进行图像处理的项目提供便利。 本压缩包文件“SIFT_using_java.rar”包含了用Java编写的SIFT算法实现。对于从事图形学或图像处理研究的开发者来说,这是一个非常有...
《VC++数字图像处理典型算法及实现》是一个深入探讨图像处理技术的资源包,主要针对使用Visual C++编程环境的开发者。这个资源包含了多种图像处理的源代码,可以帮助程序员理解和应用核心的数字图像处理算法。下面...
这有助于理解和调试SIFT算法的不同组件。 通过运行`siftDemo`,你不仅可以学习SIFT算法的基本原理,还能深入理解其在实际应用中的效果。对于想要在MATLAB中实现图像处理和计算机视觉项目的开发者来说,这是一个宝贵...
本压缩包中的“sift 特征匹配源代码”是针对SIFT算法的一种实现,特别适用于图像识别任务。由于原始下载的源代码存在问题,此处提供的版本已经过修正,可以避免运行时错误,确保了代码的可用性和稳定性。 SIFT算法...
SIFT算法是David Lowe在1999年提出的,它能在图像缩放和旋转变化下保持稳定,是一种强大的局部特征描述子。SIFT步骤主要包括以下几个关键环节: 1. **尺度空间极值检测**:通过高斯差分金字塔找到图像中的关键点。 2...
在描述中,“基于opencv的sift图像拼接和人脸识别程序代码”进一步强调了这个项目不仅涉及到SIFT算法,还包含了人脸识别的代码。OpenCV是一个广泛使用的开源计算机视觉库,提供了多种图像处理和计算机视觉的函数,...
SIFT算法的核心在于其对图像尺度变化、旋转、光照等不变性的处理能力,使得提取的特征在多种条件下保持稳定,具有高度的可重复性和独特性。 SIFT算法的主要步骤包括以下几个部分: 1. **尺度空间极值检测**:SIFT...
2. 角点检测:如Harris角点检测、SIFT、SURF算法,用于识别图像中的关键点。 3. 区域分割:包括阈值分割、区域生长、连通组件分析,用于划分图像的不同部分。 五、图像分析与识别 1. 图像配准:通过比较和调整两个...
1. **特征提取**:使用SIFT算法从图像中提取特征,这些特征可能包括关键点的位置、方向和描述符。 2. **词汇库构造**:使用聚类算法(如K-means)对所有图像的SIFT特征进行聚类,生成BOW词汇表。 3. **特征编码**:...
SIFT特征具有尺度不变性、旋转不变性和部分遮挡适应性,使其成为物体识别、图像配准、3D重建等多个计算机视觉任务中的关键组件。 在MATLAB环境中实现SIFT算法,通常包括以下几个核心步骤: 1. **尺度空间极值检测*...
SIFT算法因其强大的鲁棒性和广泛的应用场景而备受关注,在图像识别、图像匹配、物体识别等领域有着举足轻重的地位。本文将详细介绍SIFT特征检测器和描述符的实现细节,包括其工作原理、参数设置以及MATLAB环境下的...
2. **特征提取**:使用SIFT算法提取手势图像的关键点和描述子。 3. **训练模型**:使用SVM对已标注的手势图像集进行训练,构建识别模型。 4. **测试与识别**:应用训练好的SVM模型对新手势图像进行分类,得出识别...
图像特征提取是图像处理中的重要环节,例如角点检测(Harris角点检测、Shi-Tomasi角点检测)、关键点检测(SIFT、SURF、ORB等)。这些特征对于图像识别、目标检测等任务至关重要。在Visual C++中,OpenCV库提供了...
1. SIFT、SURF、ORB等特征匹配算法。 2. 卷积神经网络(CNN):深度学习框架下用于图像分类和识别。 以上知识点涵盖了VC++数字图像处理的常见算法和实现方法。通过实践这些算法,开发者可以构建功能强大的图像处理...