Почему команда ImageMagick `compare` настолько медленная и есть альтернатива?

У меня есть сценарий оболочки, работающий на небольшом полете Micro-ATX на базе Atom, которое выполняет некоторые сторожевые функции для нескольких устройств в локальной сети. Одна из вещей, которую он делает, – это мониторинг некоторых источников видео (захват экрана с виртуальных машин и канал камеры безопасности) для значительных изменений. Захват данных не кажется проблемой, но сравнение изображений, чтобы решить, является ли изменение основным, убивает ящик.

Единственное, что я делаю в любой момент в моей текущей настройке, – это команда compare ImageMagick, которую я выполняю следующим образом:

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

Это обеспечивает достаточно полезный номер, судящий, насколько похожи изображения, но навсегда нужно бежать. Я пробовал другие показатели, такие как AE с разными настройками -fuzz , но разница во времени выполнения кажется незначительной.

Я возился с парой 60K 640×480 изображений и получал время выполнения ~ 30 секунд по этой команде. Есть пара концертов с бесплатной ОЗУ, зависание – определенно процессор. Все 4 ядра были привязаны к длительности команды. Для сравнения я пробовал одни и те же изображения на моем рабочем столе, и для запуска было всего 2 секунды, что является абсурдным количеством процессорного времени для того, что я пытаюсь выполнить.

Я получил яркую идею о том, что я могу создавать эскизы и проверять, насколько они изменились. Это было достаточно легко, и я создал соответствующие 64×48 миниатюры и compare их. Результат был совсем иным, в среднем около 25 секунд. Дальнейшее сжатие до 6×4 пикселей не ускорило процесс, я все еще получал ~ 25 секунд для запуска.

Могу ли я что-то неправильно настроить? Почему эта операция настолько ресурсоемкая и почему размер изображения не имеет значения? Есть ли альтернативный способ выяснить, выросли ли два изображения более определенного порога? (Данные скриншотов проще, так как трюк с измененным пикселем делает трюк, но видеоданные имеют статическую и требуют нечеткой обработки, чтобы определить номер разницы.)

Это не проблема S / W, и, похоже, это не проблема с Atom. У меня есть Atom 330 как моя основная машина (D945GCLF2), работающая с Arch Linux – и я просто сделал этот тест:

 ttsiod@home ~/tmp $ wget i.stack.imgur.com/fWwyu.png --2014-10-29 14:30:08-- http://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 http://i.stack.imgur.com/KQiJX.png --2014-10-29 14:30:16-- http://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 двух изображений 640×400 на Atom330, составляет 1 секунду – намного быстрее, чем ваши 25 секунд.

В отсутствие выхода strace -f log из вашего запуска, единственное, что я могу догадаться, – это плохое аппаратное обеспечение (возможно, процессор с пассивным охлаждением, который снижает его скорость, чтобы избежать ловушки?) Или плохо скомпилированные двоичные файлы (например, не используя MMX / SSE).

BTW, чтобы убедиться, что ядро ​​не дросселирует вас, сделайте это сначала (как root):

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

Затем я попытался бы контролировать температуру / частоту процессора во время теста – я угадываю, что он затухает до забвения …

Для полноты, это версии ядра и 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