ImageMagick的“-subimage-search”操作是如何工作的?

7
我在我的应用程序中使用了ImageMagick。 我使用ImageMagick使用compare命令和-subimage-search选项来比较图像。
但是关于-subimage-search如何工作的文档非常少。
有人可以为我提供有关其工作原理的更多信息吗? 例如:
它是使用颜色模型进行比较还是使用图像分割来完成任务?
我现在知道的是它在第一个图像中搜索第二个图像。
但是这是如何完成的? 请解释一下。

据我所知,它只是比较子图像和主图像的像素,同时允许模糊因素,并在模糊容差范围内匹配图像时给出肯定的评价。如果有任何分割操作,我会感到非常惊讶。您可以随时查看源代码以确保。 - Mark Setchell
1个回答

19

警告:执行子图像搜索的速度非常慢,甚至极慢。

理论

这种缓慢是由于子图像搜索的工作方式所致:它在较大图像上的每个可能位置(以及当前覆盖该位置的区域)都执行一个比较操作

使用 -subimage-search 最基本的命令如下:

compare -subimage-search largeimage.ext subimage.ext resultimage.ext

执行此命令后,您应该得到两张图片:

  • results-0.ext :此图像应显示(最佳)匹配位置。
  • results-1.ext :这应该是一个潜在的左上角位置“热力图”。

第二张图片(位置图)显示子图像在相应位置的匹配程度:像素越亮,匹配程度越好。

“地图”图像的尺寸较小,因为它只包含子图像的每个潜在左上角位置,并完全适合更大的图像中。其尺寸为:

width  = width_of_largeimage  - width_of_subimage  + 1
height = height_of_largeimage - height_of_subimage + 1

搜索本身是基于颜色向量的差异进行的。因此,应该可以得到相当准确的颜色比较。

为了提高搜索的效率和速度,您可以按照以下战略计划进行:

  1. 首先,将子图像的非常非常小的子图像与较大的图像进行比较。这应该能更快地找到不同的可能位置。
  2. 然后使用步骤1的结果,在每个先前发现的潜在位置上进行差异比较,以获得更准确的匹配。

实际示例

让我们首先创建两个不同的图像:

convert rose: subimage.jpg

convert rose: -mattecolor blue -frame 20x5 largeimage.png

第一张图片,sub-image.jpg(左侧)是JPEG格式的,颜色编码会有损失,因此 sub-image 不能完全匹配。确切的匹配是不可能的。

第二张图片,largeimage.png(右侧)与主体部分周围的蓝色边框不同:

sub-image largeimage

现在开始执行 compare 命令:

time compare -subimage-search largeimage.png  subimage.jpg  resultimage.png
 @ 40,5
 real  0m17.092s
 user  0m17.015s
 sys   0m0.027s

以下是结果:

  • 左边是显示最佳匹配位置的resultimage-0.png;
  • 右边是显示潜在匹配的“热图”的resultimage-1.png

resultimage-0.png resultimage-1.png

结论:结果不正确?是Bug吗?

通过查看生成的图像并了解这两个图像是如何构建的,我认为结果不正确:

  1. 该命令应该返回@20,5而不是@40,5
  2. resultimage-0.png中的红色区域应该向左移动20个像素。
  3. 热图resultimage-1.png似乎将最佳匹配位置指示为最暗的像素;也许我对于上面的"像素越亮,匹配越好"的说法是错误的,应该是"像素越暗..."吗?

我将向ImageMagick开发人员提交一个Bug报告,看看他们对此有何回应....

更新

如@ dlemstra所建议的,我测试添加了一个-metric操作进行子图像搜索。这个操作返回一个数值,指示匹配的接近程度。有各种可用的度量标准,可以列出。

convert -list metric

在我的笔记本电脑上(运行ImageMagick v6.9.0-0 Q16 x86_64),这将返回以下列表:

AE Fuzz MAE MEPP MSE NCC PAE PHASH PSNR RMSE

这些缩写的含义如下:

  • AE : 绝对误差计数,不同像素数量(考虑 -fuzz
  • Fuzz : 平均颜色距离
  • MAE : 均值绝对误差(归一化),平均通道误差距离
  • MEPP : 每像素平均误差(归一化平均误差,归一化峰值误差)
  • MSE : 均方误差,通道误差平方平均值
  • NCC : 归一化交叉相关系数
  • PAE : 峰值绝对误差(归一化峰值绝对误差)
  • PHASH : 感知哈希
  • PSNR : 峰值信噪比
  • RMSE : 均方根误差(归一化均方根误差)

一个有趣的(并且相对较新的)指标是phash(“感知哈希”)。它是唯一不需要相同尺寸才能直接比较图像(没有 -subimage-search选项)的指标。在命令行和编程中,通常它是缩小类似图像的最佳“度量”(或者至少可靠地排除这些看起来非常不同的图像对)。

我使用像下面这样的循环运行了所有这些指标的子图像搜索:

for m in $(convert -list metric); do
    echo "METRIC $m";
    compare -metric "$m"            \
            -subimage-search        \
             largeimage.png         \
             sub-image.jpg          \
             resultimage---metric-${m}.png;
    echo;
done 

这是命令的输出结果:

METRIC AE
compare: images too dissimilar `largeimage.png' @ error/compare.c/CompareImageCommand/976.

METRIC Fuzz
1769.16 (0.0269957) @ 20,5

METRIC MAE
1271.96 (0.0194089) @ 20,5

METRIC MEPP
compare: images too dissimilar `largeimage.png' @ error/compare.c/CompareImageCommand/976.

METRIC MSE
47.7599 (0.000728769) @ 20,5

METRIC NCC
0.132653 @ 40,5

METRIC PAE
12850 (0.196078) @ 20,5

METRIC PHASH
compare: images too dissimilar `largeimage.png' @ error/compare.c/CompareImageCommand/976.

METRIC PSNR
compare: images too dissimilar `largeimage.png' @ error/compare.c/CompareImageCommand/976.

METRIC RMSE
1769.16 (0.0269957) @ 20,5

以下这些度量设置与 -subimage-search 完全不兼容,也被“图像差异过大”信息所指示:

PSNR、PHASH、MEPP、AE

(我实际上有点惊讶失败的度量包括 PHASH 在内。这可能需要进一步调查……)

以下结果图像看起来基本正确:

  1. resultimage---metric-RMSE.png
  2. resultimage---metric-FUZZ.png
  3. resultimage---metric-MAE.png
  4. resultimage---metric-MSE.png
  5. resultimage---metric-PAE.png

以下结果图像与我第一次运行时没有要求 -metric 结果的情况下看起来类似不正确:

  • resultimage---metric-NCC.png (还返回与 @ 40,5 相同的错误坐标)

以下是 Dirk Lemstra 建议使用的 -metric RMSE 的两个结果图像:

resultimage---metric-RMSE-0.png resultimage---metric-RMSE-1.png


3
我们(ImageMagick开发人员)已经看到了你的帖子。这种行为将在下一个版本中得到修复。如果您想获取更多信息,请随时报告错误。如果您指定一个错误度量,您将会获得更好的结果。例如,-metric RMSE。 - dlemstra
@dlemstra:非常感谢。我现在很忙,还在旅行中,所以缺陷报告可能要到下周才能处理。 - Kurt Pfeifle
1
太棒了!帮了很大的忙! - Mayank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接