【问题标题】:Fast algorithm for finding a small picture in big picture?在大图中找到小图的快速算法?
【发布时间】:2011-11-12 05:29:09
【问题描述】:

检查小图片是否包含在大图片中的最佳(最快)方法是什么?

(放大的图片:)

想找:

我有一个解决方案,但是速度很慢:

  • 我遍历大图的每个像素 (x,y) 并比较小图的像素 (0,0)(颜色值)。
  • 如果像素相同,我会遍历小图并与大图进行比较。如果失败,则返回大图扫描循环。

这种方法需要大约 7 秒才能在 1600x1200 的照片上找到 50x50 的图片。

也许你知道更好的算法?我知道一个软件可以在一秒钟内完成。

【问题讨论】:

  • 认为它是一个字符串匹配。有几种可用的快速字符串匹配算法。见en.wikipedia.org/wiki/String_searching_algorithm
  • @Captain 然而,减少到字符串匹配是非常重要的。我在字符串匹配方面做了很多工作,但没有看到明显、有效的减少(我有一些想法,但它们并不明显)。
  • @Konrad 我在想,针和干草堆每串一行像素,但你可能是非常正确的,因为它很重要。
  • 你的算法不应该那么慢。我怀疑您没有直接访问两个图像缓冲区(而是调用一些 GetPixel() 函数)。如果您不确定如何操作,请发布您的代码 + 2 张图片,我们可以提供帮助。
  • 每次执行此操作时是否都会获得全新的图像,或者您是否正在处理一系列大部分相同的帧?如果是后者,四叉树之类的东西可以让这变得更有效率。

标签: .net algorithm image-processing image


【解决方案1】:

数学运算convolution(可以用Fast Fourier Transform高效实现)可用于此。

【讨论】:

  • 澄清阿斯蒙德的答案。您对目标图像进行卷积(haar 小波变换也可以工作)并获得结果。然后你对源图像进行卷积并尝试找到潜在的候选结果。大多数情况下,它会为您指明正确的方向,而要比较的信息要少得多。
  • FFT ~O(N Log N) 的运行时间不是比线性搜索大吗?如果您在同一张大图片上重复搜索,这将很有用。
  • @Red Knight 和 Aasmund - 如果使用 FFT 进行卷积,如何确定目标图像和源图像是否匹配?我觉得它类似于其他人建议的字符串匹配。
  • @LastCoder:“线性”搜索(一维)在 O(n*m) 中运行,其中 m 是模式 - 所以 FFT 更好,除非 m 非常小。
  • @O_O:我对细节有点生疏,因为我已经有一段时间没有做这些事情了,但是:卷积操作(不管它是如何实现的)需要两张图像作为输入并生成一个新图像,其中位置 (x, y) 的亮度表明如果将第二张图像的角放置在 (x, y) 在第一张图片上。因此,您可以简单地找到最亮的像素,它会告诉您需要移动多少图像。
【解决方案2】:

另一个答案描述了通过图像卷积的互相关(通过乘以 ffts 来实现)。但有时您想使用规范化互相关 - 请参阅 http://scribblethink.org/Work/nvisionInterface/nip.html 了解快速实现的完整讨论和详细信息。

【讨论】:

    【解决方案3】:

    如果你知道像素值是准确的,这只是字符串匹配问题的一个特例。有很多快速的字符串匹配算法,我会从Boyer-MooreKnuth-Morris-Pratt开始。

    【讨论】:

    • 这个答案与Simone's结合使用非常棒。
    【解决方案4】:

    你的算法有一个最坏的情况O(hA*wA*hB*wB),其中hA,wA,hB,wB 是大图像A 和小图像B 的高度和宽度。

    这个算法应该有一个最坏的情况O((wA+wB)*hA*hB)

    它基于字符串匹配,它是这样工作的:

    • 每次使用字符串匹配在图像A的每一行中查找图像B的每一行。
      • 每次匹配时,在数组matched_row 中存储一个三元组(rA, cA, rB),其中(rA, cA) 表示文件BrB 行的图像A 中的起点。
    • 现在您首先根据cAmatched_row 进行排序,然后对rA 排序,然后再对rB 排序。
    • 现在你迭代数组,如果你匹配了一个 5 行的图像 B,你会得到这样的结果:

          (12, 5, 0), (13, 5, 1), (14, 5, 2), (15, 5, 3), (15, 5, 4)
      

    【讨论】:

    • "现在我们简单地将 stringB 与 stringA 匹配" -- 你能解释一下吗? stringB 包含虚拟字符。我认为这行不通。
    猜你喜欢
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 2021-06-07
    • 2018-01-26
    相关资源
    最近更新 更多