如何使用Opencv存储大量图像的Hierarchical K-Means树?

时间:2011-04-02 05:46:14

标签: algorithm image-processing computer-vision feature-detection

我正在尝试制作一个可以从图像数据集中找到类似图像的程序。步骤是

  • 提取所有图像的SURF描述符
  • 存储描述符
  • 在存储的描述符上应用knn
  • 使用kNN
  • 将存储的描述符与查询图像描述符进行匹配

现在每个图像SURF描述符将被存储为分层k-means树,现在我将每个树存储为单独的文件,或者是否可以构建某种具有所有图像描述符的单个树并在添加图像时更新到数据集。

This is the paper I am basing the program on.

2 个答案:

答案 0 :(得分:7)

您是否确定要使用SURF描述符进行此操作?我自己正在研究一个类似的应用程序,它基于this论文(Nister,Stewenius),他们发誓 SIFT描述符是要走的路。但是,我猜你也可以用任何其他描述符来做。

看一下你引用的论文,我链接到的作品比较新,但它没有引用Nister paperthis work(Sivic,Zisserman),据我所知,该基础适用于所有基于内容的图像检索问题。

为了更好地理解这个问题,在我开始实现它之前,我首先阅读Sivic, Zisserman以获得系统背后的一般概念。它们仅在从所有要素中提取所有SIFT描述符后应用简单聚类。它们使用两种不同类型的特征以获得更好的精确度,形状适应(以角落为中心的特征)和最大稳定(对应于高对比度的斑点 - 您可以在this纸张中查找它们(Matas等人) )。由于每个功能的直接存储,他们的系统的可扩展性并不是那么好,但他们引入了Inverted文件的概念,这是Text Analytics的一种技术(你可以阅读它的基础知识here),这简化了外观过程显着。

在征服了这项工作之后,我建议继续Nister, Stewenius,在那里他们引入了L级的分层k-means聚类概念,用于存储特征,以及后者搜索图像数据库。现在,除非我非常错误,否则不要将每个描述符存储为单独的树。相反,您可以根据现有功能创建树(其中每个级别的集群中心实际上是代表性的“中心”,每个集群的功能)。一旦树被构造到所需的深度(他们建议在6个级别上有10个集群),最后一级的集群中心代表了非常少的特征 - 因此,您实际上可以忘记所有原始特征! (或至少,他们的描述符)。每个原始要素都可以由相应的群集中心表示,而不是描述符,对于每个图像,您只需要存储有关哪些群集中心 - 功能 - 包含的信息。这更容易,因为您只需要为每个功能存储一个或两个整数 - 通过树编码它的路径。最简单的方法是,如果你只是在每个级别编码特征所属的集群的数量 - 其中有10个(4位) - 对于每个级别(其中6个,4 * 6 <32位,所以它适合整数)。您当然可以以您认为合适的方式实现实际编码。哦,他们还在MSER区域使用SIFT描述符。

此外,如果您用于构建词汇表树的图像具有代表性(例如,您正在处理开放空间图片的数据集,并且您仅从图像的代表性部分构建树,但您知道没有在数据集的其余部分的工业工厂工作场所的图片),您可以非常快速地添加新图片。要在数据集中添加任何新图片,您唯一需要做的就是确定哪个计算出的聚类中心最能代表图像特征(如前所述,最后一级聚类中心非常精确)并存储有关集群中心(前面提到的整数)。查找集群中心应该非常快 - 在6个级别中每个级别只有10个比较。

希望有一天这对某人有用,因为这个问题只有一年多了。 :)

答案 1 :(得分:2)

请改用KD-Tree。您将能够构建分层K维树,您只需要确定在树下发送哪种信息以进行存储。您可以将图像的矢量/描述符保存到磁盘上,每次启动程序时都加载KD树。新的计算机向量/描述符可以发送到树和磁盘

  

总结

  • 创建描述符
  • 将新描述符提供给KD-Tree
  • 将相同的描述符保存到disk \
  • 每次重新启动时,将所有描述符加载到树
  • 查询树以获得最佳匹配

希望这有帮助