OpenCV / SURF 如何通过描述符生成图像哈希 / 指纹 / 签名?

39
这里有一些关于如何查找相似图片的非常有用的主题。
我想要做的是获取图片的指纹,并在由数码相机拍摄的不同照片中找到相同的图片。SURF算法似乎是独立于缩放、角度和其他扭曲的最佳方法。
我正在使用带有SURF算法的OpenCV提取样本图像上的特征。现在我想知道如何将所有这些特征数据(位置、Laplacian、大小、方向、Hessian)转换为指纹或哈希。
这个指纹将存储在数据库中,一个搜索查询必须能够比较这个指纹与几乎具有相同特征的照片的指纹。
更新:
似乎没有办法将所有描述符向量转换为简单的哈希。那么将图像描述符存储在数据库中以进行快速查询的最佳方法是什么?
词汇树是否是一个选择?
我将非常感谢任何帮助。

1
简而言之,您无法将图像制作成哈希函数(这太不明智和妄自尊大了)。您可以参考文献以获取最近邻分类或图像相似度测量的信息。 - elijah
非常感谢你的帮助,Liza!通过你的提示,这一切对我来说变得更加清晰。 - dan
你发布这个问题已经将近两年了。我想做的事情几乎完全相同...你有什么进展吗?哪些方法有效,哪些无效?是否可能创建哈希或至少是SURF描述符的简明表示以进行快速查找? - mpen
你找到任何方法了吗?我也有同样的问题,但是找不到解决方案。谢谢! - lilouch
任何解决方案都需要找到某种哈希函数。 - Qazi Ammar
显示剩余3条评论
4个回答

10
你提到的特征数据(位置、拉普拉斯、大小、方向、海森矩阵)对于你的目的来说是不足的(如果你想进行匹配,这些实际上是描述符中不太相关的部分)。你想查看的数据是“描述符”(第四个参数): void cvExtractSURF(const CvArr* image, const CvArr* mask, CvSeq** keypoints, CvSeq** descriptors, CvMemStorage* storage, CvSURFParams params) 这些是包含特定特征“指纹”的128或64个向量(每个图像将包含可变数量的这些向量)。 如果你获取最新版本的OpenCV,它们有一个名为find_obj.cpp的示例,展示了如何用于匹配。 更新: 你可能会发现this的讨论有帮助。

嗨Liza,谢谢你的回复。我看了这个例子,但是没有找到任何将存储在CvSeq中的描述符向量转换为哈希值的方法,以便可以将其存储在数据库中并与其他哈希值进行比较。你有什么提示吗? - dan
CvSeq仅存储浮点数数组(查看cvExtractSURF的源代码以了解它们的存储方式)。这些数组(长度为128或64)是您感兴趣的内容。 - elijah
顺便说一句,如果你想得到一个神奇的哈希值,将所有狗的图像映射到相同的哈希值,恐怕这比仅仅提取SURF特征更加复杂。请查看我在更新中提供的链接。 - elijah
1
Liza,非常感谢你的帮助。你说得对,我正在寻找一种哈希指纹作为每个图像的数字字符串,以便可以将其存储在关系型数据库中。然后,我想计算两个图像之间的汉明距离,以检查这些图像是否几乎相同。我的问题是我不知道如何将描述符向量数据转换为这样的字符串 - 就像pHash库所做的那样。 - dan
我已经更新了我的问题,澄清了我所说的线性哈希的含义。 - dan
显示剩余3条评论

3
计算哈希的一个简单方法如下。从图像中获取所有描述符(假设有N个)。每个描述符是一个由128个数字组成的向量(可以将它们转换为介于0和255之间的整数)。因此,您有一组N*128个整数。只需将它们顺序写入一个字符串中,并将其用作哈希值即可。如果您希望哈希值很小,我相信有一些方法可以计算字符串的哈希函数,因此将描述符转换为字符串,然后使用该字符串的哈希值。
如果您想要查找相似的图像,那么上述方法可能无法胜任,因为它只能用于查找完全重复的图像。在这种情况下,使用哈希可能不是一个好的选择,因为您可能需要使用某些兴趣点检测器来查找要计算SURF描述符的点。假设它会以不同的顺序返回相同的点。即使图像和描述符相同,您的哈希值也会非常不同。
因此,如果我必须可靠地查找相似的图像,我会采用不同的方法。例如,我可以对SURF描述符进行矢量量化,构建矢量量化值的直方图,并使用直方图交集进行匹配。您是否真的绝对必须使用哈希函数(可能是为了效率),还是只想使用任何方法来查找相似的图像?

嗨,谢尔顿,感谢您的回复。在研究SURF之前,我一直在使用pHash库。该库为媒体数据(图像、视频和音频)生成哈希值。然后,您可以使用汉明距离轻松查询相似图像哈希的数据库。我认为一定有一种方法可以以某种方式使用SURF描述符来完成相同的操作。现在,我正在考虑将所有序列化的图像描述符数组对象存储在数据库中。当我想在数据库中查找类似图像时,我必须逐行选择并手动查找相似描述符。 (...) - dan
2
唯一的缺点是对于大型图像数据库来说性能非常差。我在想TinEye.com如何能够如此快速地找到相似的图像。他们一定有一些技巧可以快速查询他们的数据库。 - dan
1
我认为有助于解决问题的是,您告诉我们您想要实现什么目标。给定一张图片,您想要找到什么?相同的图片、相似的图片、相似的图片包括旋转/平移缩放?给定一张图片X,您只想要找到与X相似的图片,还是您也想要包含X作为子部分的图片?例如,查询是一张人脸图片。您想要找到其他人脸图片,还是包含人脸但同时也包含很多其他内容的全身照片?为什么您停止使用pHash并决定改用SURF描述符呢? - user245973
1
我想实现的是建立一个包含示例图像签名的数据库。然后我想打印出这些示例图像,用我的手机拍照。接下来我想尝试将这些照片与数据库中的原始图像进行匹配。由于这些照片会有不同的光照并且可能会略微扭曲,所以pHash算法不适用,因为该库对光照和其他误差源不够宽容。SURF算法效果很好。我唯一的问题在于以有效的方式将描述符存储在数据库中以进行快速查询。 - dan
丹,我也有同样的问题。你找到实现这个的方法了吗? - lilouch

2

2
Min-Hashmin-Hashing 是一种可能会有所帮助的技术。它将整个图像编码为可调整大小的表示形式,然后存储在哈希表中。存在几个变体,例如几何 min-Hashing划分 min-Hash包 min-Hashing。结果的内存占用并不是最小的,但这些技术适用于各种情况,如近似重复检索,甚至是小对象检索——在其他短签名经常表现不佳的场景中。
关于这个主题有几篇论文。入门文献是: Near Duplicate Image Detection: min-Hash and tf-idf Weighting Ondrej Chum, James Philbin, Andrew Zisserman, BMVC 2008PDF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接