【论文笔记】VLAD特征:Aggregating local descriptors into a compact image representation

摘要

大尺度的图像搜算需要考虑三个约束:精确性,效率,存储使用。

  • 我们首先提出一个简单但有效的方式,去将局部图像描述子聚合成一个有限维的向量,可视为一个简化的Fisher kernel表示。
  • 然后,我们联合优化降维和索引算法,尽可能的保留向量比较的质量。
  • 我们的结果展示:我们的方法在一个用20byte表示的图像上,与BOF(词袋向量特征)有相当的精确性,但是我们在搜索效率上有着巨大的提升 。

1. 导言

-词袋模型精确度高源于:1. 有力的局部描述子如SIFT。2. 这些向量表示可以用标准距离进行比较。但是它的缺点在于:当数据库数据过大时变得不可用。
我们重点讨论了搜索精度、搜索效率和内存使用三个约束条件的联合优化问题,后两个因素的相关的,因为搜索效率是能够被近似于之前参观过的地方的总共所占的memory数。
我们的方法通常使用20字节的表示,从而获得更高的精度。通过优化得到:

  1. 表示,即如何将局部图像描述符聚合为向量表示;
  2. 这些向量的降维;
  3. 索引算法。
    这些步骤是密切相关的:用高维向量表示图像通常比用低维向量提供更好的穷举搜索结果。然而,高维向量很难有效地索引。相比之下,低维向量更容易建立索引,但其识别能力较低,可能不足以识别对象或场景。
  • 我们提出了一个描述符,它来自于BOF和Fisher核, 聚合SIFT描述子并且生成一个更紧凑的表示,我们把它称作VLAD。实验结果表明,在相同尺寸下,VLAD的性能明显优于BOF。它的计算成本更低,而且通过主成分分析(PCA)可以将其维数减少到几百个分量,而不会显著影响其准确性。
  • 我们证明了联合优化降维与指数化算法之间的权衡的好处。我们特别考虑了最近[1]的索引方法,因为我们可以直接比较PCA引起的错误和索引造成的错误,这是由于矢量编码索引的近似重构造成的。

2.图像表示

在本节中,我们将简要回顾两种流行的方法,它们从一组局部描述符生成图像的向量表示。然后,我们提出了聚合本地描述符的方法。

  1. BOF词袋特征

博主补基础去了,过几天更新新!

参考文献

【1】H. Jegou, M. Douze, and C. Schmid. Product quantization for nearest neighbor search. PAMI. To appear.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VLAD(Vector of Locally Aggregated Descriptors)是一种图像表示方法,常用于图像检索和计算机视觉任务中。它通过聚合局部特征描述符来生成图像的紧凑表示。 以下是一个简单的C++实现示例,展示了如何实现VLAD图像表示: ```cpp #include <iostream> #include <vector> #include <opencv2/opencv.hpp> // 聚类算法(这里使用K-means) cv::Mat kmeansClustering(const std::vector<cv::Mat>& descriptors, int numClusters) { cv::Mat allDescriptors; for (const cv::Mat& descriptor : descriptors) { allDescriptors.push_back(descriptor); } cv::Mat labels, centers; cv::TermCriteria criteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 100, 0.01); cv::kmeans(allDescriptors, numClusters, labels, criteria, 1, cv::KMEANS_PP_CENTERS, centers); return centers; } // 计算VLAD图像表示 cv::Mat computeVLAD(const std::vector<cv::Mat>& descriptors, const cv::Mat& visualWords) { int descriptorSize = descriptors[0].cols; cv::Mat vlad(visualWords.rows, descriptorSize, CV_32F, cv::Scalar(0)); for (const cv::Mat& descriptor : descriptors) { // 找到每个描述符最近的视觉词 cv::Mat difference = visualWords - descriptor; cv::Mat distances; cv::reduce(difference.mul(difference), distances, 1, cv::REDUCE_SUM); cv::Point minLoc; cv::minMaxLoc(distances, nullptr, nullptr, &minLoc); // 计算每个视觉词的残差 cv::Mat residual = descriptor - visualWords.row(minLoc.y); // 更新VLAD表示 for (int i = 0; i < descriptorSize; i++) { vlad.at<float>(minLoc.y, i) += residual.at<float>(0, i); } } // 归一化VLAD表示 cv::normalize(vlad, vlad, 1.0, 0.0, cv::NORM_L2); return vlad; } int main() { // 假设有一组局部特征描述符(使用OpenCV的Mat表示) std::vector<cv::Mat> descriptors = { (cv::Mat_<float>(1, 128) << /* descriptor values */ ), (cv::Mat_<float>(1, 128) << /* descriptor values */ ), (cv::Mat_<float>(1, 128) << /* descriptor values */ ), // ... }; // 聚类算法,得到视觉词汇 int numClusters = 100; cv::Mat visualWords = kmeansClustering(descriptors, numClusters); // 计算VLAD图像表示 cv::Mat vlad = computeVLAD(descriptors, visualWords); // 输出VLAD表示结果 std::cout << "VLAD Representation:\n" << vlad << std::endl; return 0; } ``` 在这个示例中,`descriptors`是一组局部特征描述符,每个描述符用一个`cv::Mat`对象表示。首先,使用K-means聚类算法将所有描述符聚类成`numClusters`个视觉词汇,并得到`visualWords`矩阵。然后,根据每个描述符找到最近的视觉词,并计算每个视觉词的残差。将残差累加到VLAD表示中,并进行归一化处理。最后,输出VLAD图像表示结果。 请注意,这只是一个简单的VLAD图像表示的C++实现示例,供你参考。在实际应用中,你可能需要根据具体需求进行修改和扩展,例如使用更复杂的特征提取方法、改进聚类算法等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值