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