【问题标题】:Image hashing in c++, with similar images featurec++中的图像散列,具有相似的图像特征
【发布时间】:2016-05-05 16:42:30
【问题描述】:

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

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

问题描述

我们有一个函数ReturnType foo(Image),它获取一张图像,对其进行一些耗时的计算并返回一些东西(这取决于应用程序)。我正在设计的 memoizator 是一个unordered_map<ImageHash,ReturnType>(或等效结构),因此如果用户两次提交相同的图像,它会直接返回已经计算的ReturnType 值。

我需要什么

如你所想,我需要一些HashFunction s.t. HashFunction(Image)=ImageHash,其中ImageHash 很有可能是唯一的。

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

由于性能确实至关重要,因此快速散列函数会很好。

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

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

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

下一步

我想扩展之前的解决方案,以便我们为相似图像返回相同的结果。正式地,给定Image image1 类似于Image image2,那么如果image1 之前已经计算过image1,系统将返回ReturnType result

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

【问题讨论】:

  • md5 是这类事情的常用哈希算法。至于使用散列来匹配相似的图像,我认为这是行不通的——散列码在很大程度上取决于用于生成它们的确切字节序列,并且(据我所知)没有任何方法使用它们来测试不精确的相等性。
  • @JeremyFriesner 所以 sha-1 也不错 :)

标签: c++ image hash memoization


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回答,非常感谢。你能解释一下如何从图像中创建一些 n 维向量吗?我认为这是这样一个过程的基础:)
【解决方案2】:

如果您使用 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 unordered_map 并让 unordered_map 调用哈希函数而不是使用您调用的哈希函数的结果作为键,则需要提供 hash&lt;key&gt; 参数。

【讨论】:

  • 更新:ImageHash 必须是唯一的,概率很高。
  • @justHelloWorld 我想我看不出你为什么不让 unordered_map 做它的事情,如果你需要的话,你甚至可以从 unordered_map 获取散列值
猜你喜欢
  • 2017-08-30
  • 2018-07-03
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 2019-07-18
  • 2021-04-12
相关资源
最近更新 更多