为什么 ImageMagick 的“compare”命令这么慢,有替代方法吗?

为什么 ImageMagick 的“compare”命令这么慢,有替代方法吗?

我有一个 shell 脚本在一个基于 Atom 的小型 Micro-ATX 盒子上运行,它为本地网络上的许多设备执行一些类似看门狗的功能。它所做的事情之一是监视一些视频源(来自虚拟机的屏幕截图和安全摄像头源)是否发生重大变化。捕获数据似乎不是问题,但通过比较图像来确定变化是否重大就毁掉了盒子。

在我当前的设置中唯一需要时间的是 ImageMagick 的compare命令,我正在执行它,如下所示:

compare -metric PHASH previous.png current.png null:

这提供了一个相当有用的数字来判断图像的相似程度,但它需要永远跑步。我尝试了其他指标,例如AE不同的-fuzz设置,但运行时差异似乎可以忽略不计。

我正在摆弄一对 60K 640x480 图像,并且该命令的运行时间约为 30 秒。有几GB空闲RAM,挂起的肯定是CPU。在命令执行期间,所有 4 个核心都处于挂起状态。为了进行比较,我在我的 fatso 桌面上尝试了相同的图像,运行时间几乎为 2 秒,这对于我想要完成的任务来说是一个荒谬的 CPU 时间。

我想到了一个好主意,我可以生成缩略图并检查它们发生了多少变化。这很简单,我生成了匹配的 64x48 缩略图并compare在这些缩略图上运行。结果几乎没有什么不同,平均约为 25 秒。进一步压缩为 6x4 像素图像并没有加快进程太多,我仍然有大约 25 秒的时间运行。

我可能配置错误吗?为什么这个操作如此消耗资源并且为什么图像的大小似乎并不重要?是否有其他方法可以确定两个图像的泄露是否超过某个阈值? (屏幕截图数据更容易,因为硬改变像素数可以解决问题,但视频数据是静态的,需要模糊处理来找出差异数。)

答案1

这不是S/W的问题,而且看起来也不是Atom的问题。我有一台 Atom 330 作为我的主机 (D945GCLF2),运行 Arch Linux - 我刚刚做了这个测试:

ttsiod@home ~/tmp
$ wget i.stack.imgur.com/fWwyu.png
--2014-10-29 14:30:08--  https://i.stack.imgur.com/fWwyu.png
Resolving i.stack.imgur.com (i.stack.imgur.com)... 103.31.7.31...
Connecting to i.stack.imgur.com (i.stack.imgur.com)|103.31.7.31|:80...
HTTP request sent, awaiting response... 200 OK
Length: 28576 (28K) [image/png]
Saving to: `fWwyu.png'

100%[==============================>] 28,576   --.-K/s   in 0.06s   

2014-10-29 14:30:09 (446 KB/s) - `fWwyu.png' saved [28576/28576]

ttsiod@home ~/tmp
$ wget https://i.stack.imgur.com/KQiJX.png
--2014-10-29 14:30:16--  https://i.stack.imgur.com/KQiJX.png
Resolving i.stack.imgur.com (i.stack.imgur.com)... 103.31.6.184
Connecting to i.stack.imgur.com (i.stack.imgur.com)|103.31.6.184|:80...
HTTP request sent, awaiting response... 200 OK
Length: 28212 (28K) [image/png]
Saving to: `KQiJX.png'

100%[==============================>] 28,212  --.-K/s   in 0.06s   

2014-10-29 14:30:17 (431 KB/s) - `KQiJX.png' saved [28212/28212]


ttsiod@home ~/tmp
$ identify KQiJX.png 
KQiJX.png PNG 640x400 640x400+0+0 8-bit sRGB 28.2KB 0.000u 0:00.000

ttsiod@home ~/tmp
$ time compare -metric PHASH fWwyu.png KQiJX.png null:
0.191664
real    0m1.029s
user    0m2.863s
sys     0m0.177s

ttsiod@home ~/tmp
$ time compare -metric PHASH fWwyu.png fWwyu.png null:
0
real    0m1.027s
user    0m2.843s
sys     0m0.190s

compare因此,在 Atom330 上生成两张 640x400 图像所需的时间为 1 秒 - 比 25 秒快得多。

在运行中没有日志输出的情况下strace -f,我唯一能猜测的是......硬件不好(可能是被动冷却的CPU,降低了速度以避免着火?)或编译错误的二进制文件(例如不使用MMX/SSE)扩展)。

顺便说一句,为了确保内核不会限制您,请首先执行此操作(以 root 身份):

for i in /sys/devices/system/cpu/cpu?/cpufreq/scaling_governor ; do
    echo performance > $i
done

然后我会尝试在测试过程中监控CPU的温度/频率——我猜它会降低速度直到被遗忘......

为了完整起见,这些是compare我在上面的测试中使用的内核和版本:

ttsiod@home ~/tmp
$ egrep '^model.na|^flags'  /proc/cpuinfo   | sort -u
model name      : Intel(R) Atom(TM) CPU  330   @ 1.60GHz
flags           : fpu vme de tsc msr pae mce cx8 apic sep 
                  mtrr pge mca cmov pat clflush dts acpi
                  mmx fxsr sse sse2 ss ht tm pbe syscall
                  nx lm constant_tsc arch_perfmon pebs
                  bts nopl aperfmperf pni dtes64 monitor
                  ds_cpl tm2 ssse3 cx16 xtpr pdcm movbe
                  lahf_lm dtherm

ttsiod@home ~/tmp
$ uname -a
Linux home 3.16.3-1-ARCH #1 SMP PREEMPT Wed Sep 17 21:54:13
                                CEST 2014 x86_64 GNU/Linux

ttsiod@home ~/tmp
$ compare --version
Version: ImageMagick 6.8.9-9 Q16 x86_64 2014-10-26 http://www.imagemagick.o
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC HDRI Modules OpenCL OpenMP
Delegates: bzlib cairo fontconfig freetype gslib jng jp2 jpeg lcms lqr ltdl
           lzma pangocairo png ps rsvg tiff webp wmf x xml zlib

相关内容