.net 在大画面中寻找小画面的快速算法?

.net 在大画面中寻找小画面的快速算法?,.net,algorithm,image-processing,image,.net,Algorithm,Image Processing,Image,检查小图片是否在大图片中的最佳(最快)方法是什么? (放大图片:) 想要找到: 我有一个解决方案,但速度非常慢: 我遍历大图片中的每个像素(x,y),并比较小图片(颜色值)的像素(0,0) 如果像素是相同的,我迭代小图片,并将其与大图片进行比较。。如果失败,它将返回到大图像扫描循环 这种方法需要大约7秒钟才能在1600x1200照片上找到一张50x50的照片 也许你知道一个更好的算法?我知道一个软件可以在一秒钟内完成这项工作。数学运算(可以用有效地实现)可以用于此。另一个答案描述了通过图像

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

(放大图片:)

想要找到:

我有一个解决方案,但速度非常慢:

  • 我遍历大图片中的每个像素(x,y),并比较小图片(颜色值)的像素(0,0)
  • 如果像素是相同的,我迭代小图片,并将其与大图片进行比较。。如果失败,它将返回到大图像扫描循环
这种方法需要大约7秒钟才能在1600x1200照片上找到一张50x50的照片


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

数学运算(可以用有效地实现)可以用于此。

另一个答案描述了通过图像卷积(通过乘以FFT实现)实现的互相关。但有时您希望使用规范化互相关-有关快速实现的完整讨论和详细信息,请参阅。

如果您知道像素值将是精确的,这将成为字符串匹配问题的特例。有很多快速字符串匹配算法,我从or开始。

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

该算法的最坏情况应该是
O((wA+wB)*hA*hB)

它基于字符串匹配,其工作原理如下:

  • 每次使用字符串匹配在图像的每行
    A
    中查找图像的每行
    B
    • 每次有匹配项时,在数组
      matched_行
      中存储三元组
      (rA,cA,rB)
      ,其中
      (rA,cA)
      表示文件
      B
      行的
      rB
      图像
      a
      中的起点
  • 现在,首先根据
    cA
    matched\u行进行排序,然后排序到
    rA
    ,然后排序到
    rB
  • 现在迭代数组,如果匹配5行的图像B,则会得到如下结果:

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

将其视为字符串匹配。有几种快速字符串匹配算法可用。但是,请参见“字符串匹配”的缩减是非常重要的。我在字符串匹配方面做了很多工作,但我看不到明显、有效的减少(我有一些想法,但它们一点都不明显)。@Konrad我在想,针和草堆的每行字符串都有一行像素,但你可能认为这是非常重要的。你的算法不应该那么慢。我怀疑您没有直接访问这两个图像缓冲区(而是调用一些GetPixel()函数)。如果您不确定如何做到这一点,请发布您的代码+2张图片,我们可以提供帮助。每次这样做时,您会得到一个全新的图像,还是会处理一系列基本相同的帧?如果是后者,像四叉树这样的东西可以使这更有效。对目标图像进行卷积(haar小波变换也可以),然后得到结果。然后对源图像进行卷积,并试图找到潜在的候选结果。在大多数情况下,它会为您指出正确的方向,而您需要比较的信息要少得多。FFT~O(N Log N)的运行时间不是比线性搜索的运行时间大吗?如果在同一幅大图像上重复搜索,这将非常有用。@Red Knight和Aasmund-如果使用FFT进行卷积,如何确定目标图像和源图像是否匹配?我觉得这和其他人建议的字符串匹配类似。@LastCoder:一个“线性”搜索(一维)在O(n*m)中运行,其中m是模式的长度-所以FFT更好,除非m非常小。@O_O:我对细节有点生疏,因为我已经有一段时间没有做这类事情了,但是:卷积运算(无论如何实现)将两个图像作为输入,并生成一个新图像,其中位置(x,y)的亮度表示如果第二个图像的角点位于第一个图像的(x,y)上,图像的匹配程度。因此,您可以简单地定位最亮的像素,这将告诉您需要移动图像多少。“现在我们只需将stringB与stringA进行匹配”--你能解释一下吗?stringB包含虚拟字符。我认为这不起作用。当与stringA结合使用时,这个答案非常好。