我正在尝试从Oxford building dataset创建SIFT描述符的数据集。
它是大约5k图像,并使用1024pxs的最大尺寸(宽度或高度)的默认值。使用默认的VLFeat implementation,它可以为每个图像平均生成10k个关键点。
现在,让我们做一些数学计算所需的内存来将所有描述符存储在内存中:
10 ^ 3(每个图像平均#关键点)* 5 * 10 ^ 3(图像)* 128(描述符维度)* 32(浮点表示)/ 8(字节)/ 10 ^ 6(GB)= 2560 GB < / p> 哇,那是很多记忆! :D所以我的问题很简单:我在上一行中写错了什么,或者我们真的需要所有这些内存?这很奇怪,因为这是真正着名的对象识别算法。怎么了?
答案 0 :(得分:1)
在这个答案中,我将首先谈谈如何将单个图像中的功能数量减少到比10k更合理的数量。接下来,我尝试解释如何保存所有提取的功能。哦,并回答你的问题:我认为你在将字节转换为千兆字节时犯了一个错误:1千兆字节是1024 ^ 3字节,所以我计算~2.4 GB。
您可能不会为每张图片提供10k SIFT功能,以实现可靠的匹配。许多检测到的特征将对应于非常小的梯度,并且很可能是噪声。 vl_sift
函数的文档为您提供了两种控制描述符点数的方法:
PeakThresh
。这是一个应用于梯度差异(DoG)图像的阈值,因此只有DoG中具有大峰值的点,即大且不同的梯度才被视为特征。edgethresh
。由于我们只需要键点而不是整个边缘,因此会删除它们。可以使用edgethresh
参数控制此过程,其中较高的值可为您提供更多功能。这有助于您将功能数量减少到合理的数量,即您可以处理的数量(这取决于您的基础架构,您的需求和耐心等)。这适用于小规模检索应用程序。但是,对于大规模图像检索,您可能拥有数千或数百万个图像。即使每个图像只有10个描述符,您仍然难以处理这个问题。
要解决此问题,请在提取的描述符上运行k-means聚类,这将为您提供所谓的&#34; Visual Words&#34;的数字 k 。 (遵循文本检索术语)。接下来,您构建一个反向索引,它与书籍索引完全相同:您保存,在书的哪个页面上提到哪个词 - 或者在这里:哪个视觉词出现在哪个图像中。
对于新图像,您所要做的就是为每个描述符找到最近的可视单词,并使用反向索引查看哪个数据库图像包含与查询图像相同的可视单词。
这样,你需要保存的只是视觉词的质心。视觉词的数量可以是任何东西,但是我说在100到10k之间的范围通常是合理的。