c ++中的图像散列,具有类似的图像功能

时间:2016-05-05 04:07:35

标签: c++ image hash memoization

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

要知道的第一件事:我对图像处理一无所知,所以请对这个可怜的家伙保持温和:)

问题说明

我们有一个函数ReturnType foo(Image),它接受​​一个图像,对它进行一些时间昂贵的计算并返回一些东西(取决于应用程序)。我设计的备忘录是unordered_map<ImageHash,ReturnType>(或等效结构),因此如果用户提交两次相同的图像,则直接返回已计算的ReturnType值。

我需要什么

你可以想象,我需要一些HashFunction s.t. HashFunction(Image)=ImageHash,其中ImageHash具有很高的概率。

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

由于性能非常重要,快速哈希函数会很好。

我找到了关于这个主题的this question,但是作者在图像上引入了很多限制(并且在成瘾中没有给出好的解决方案)。

注意:图片没有任何限制,因此您可以提出您喜欢的任何解决方案(包括其设计的图像集)。

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

下一步

我想扩展之前的解决方案,以便为类似图片返回相同的结果。正式地说,如果Image image1Image image2相似,那么如果ReturnType result image1,则系统会为(image1,result)返回(image2,result)以前已经计算好了。

我已经听说过phash,但我不知道它是否适合此目的。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

如果您使用stl unordered_map

,我只需要一点注释

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

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

  

每个元素只有在其键不等同于容器中已有的任何其他元素的键时才会插入(unordered_map中的键是唯一的)。

密钥必须属于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 hash<key>并让unordered_map调用散列函数而不是使用您调用的散列函数的结果,则需要提供unordered_map参数关键。