c ++中的图像哈希,具有相似的图像特征

Image hashing in c++, with similar images feature

我正在为类似图像开发一个 memoization 系统。我会将这个问题分成两个子问题,因为一个是另一个的下一步,但如果您认为更合适,我可以 post 两个不同的问题。

首先要知道:我对图像处理一无所知,所以请对这个可怜的家伙温柔点:)

问题描述

我们有一个函数 ReturnType foo(Image) 可以拍摄图像,对其进行一些耗时的计算,然后 return 就可以了(这取决于应用程序)。我正在设计的 memoizator 是一个 unordered_map<ImageHash,ReturnType>(或等效结构),因此如果用户两次提交相同的图像,它 return 直接是已经计算出的 ReturnType 值。

我需要什么

如你所想,我需要一些 HashFunction s.t。 HashFunction(Image)=ImageHash,其中 ImageHash 是唯一的且概率很高。

请注意,此 ImageHash 必须 不依赖于特定的 运行、机器、时间。这是因为 unordered_map 将在文件中序列化(因此它可以在不同的 运行 中使用)并与其他用户共享。

由于性能真的很重要,所以快速哈希函数会很好。

找了this question关于题目,但是作者在图片上引入了很多限制条件(沉迷也没有给出好的解决办法)

注意:图像没有限制,所以你可以提出任何你喜欢的解决方案(包括它设计的图像集)。

注意: SHA-1 可能是一种可能的解决方案吗?我只将它用于字符串,我不知道是否可以将它用于图像(如果它存在 C++ 实现)

下一步

我想扩展之前的解决方案,因此我们 return 相似图像 的结果相同。所以正式地,给定 Image image1 类似于 Image image2,那么系统 returns ReturnType result for image1 if (image1,result) OR (image2,result) 之前已经计算过。

我听说过 phash 但我不知道它是否适合这个目的。

如果你使用 stl,我只是有一点旁注 unordered_map

如果您使用 unordered_map<ImageHash,ReturnType> 并将散列结果作为键,则缓存计算结果将不起作用。如果两个图像的哈希值相同,则不会插入第二个图像。

来自http://www.cplusplus.com/reference/unordered_map/unordered_map/insert/

Each element is inserted only if its key is not equivalent to the key of any other element already in the container (keys in an unordered_map are unique).

密钥必须是 Image 类型,以便 unordered_map 可以正确处理散列冲突。

来自http://www.cplusplus.com/reference/unordered_map/unordered_map/

template < class Key,                                    // unordered_map::key_type
           class T,                                      // unordered_map::mapped_type
           class Hash = hash<Key>,                       // unordered_map::hasher
           class Pred = equal_to<Key>,                   // unordered_map::key_equal
           class Alloc = allocator< pair<const Key,T> >  // unordered_map::allocator_type
           > class unordered_map;

如果您最终使用 stl unordered_map 并让 unordered_map 调用散列函数而不是使用散列函数的结果,您将需要提供一个 hash<key> 参数调用作为关键。

我建议你先开始收集一些图像,然后再继续。话虽如此,目前最好的方法是使用深度学习学习相似度函数并将图像映射到一些 n 维特征 space 并使用余弦距离来衡量相似度。下面是一些帮助您入门的示例代码 (https://github.com/kevinlin311tw/caffe-cvprw15)。如果您想要更高性能的技术并且愿意跟随兔子洞,请查看三元组排名损失。

Phash 工作正常,但它在产生相似性分数方面的表现远低于使用深度学习功能的表现。然而,它肯定比真正的散列技术更好,因为只要改变 jpeg 压缩级别就会改变散列值。如果你不想在这上面花太多时间,phash 将是最好的选择,因为它使用起来毫不费力。