3

I have a shell script running on an little Atom based Micro-ATX box that is doing some watchdog-like functions for a number of devices on a local network. One of the things it's doing is monitoring some video sources (screen captures from VM's and a security camera feed) for significant changes. Capturing the data doesn't seem to be a problem, but comparing images to decide if the change is major is killing the box.

The only thing taking any time at all in my current setup is ImageMagick's compare command which I'm executing like this:

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

This provides a fairly usable number judging how similar the images are, but it takes forever to run. I tried other metrics such as AE with different -fuzz settings but the run-time difference seems to be negligible.

I was messing around with a pair of 60K 640x480 images and was getting run times ~30 seconds on that command. There is a couple gigs of free RAM, the hang up was definitely CPU. All 4 cores were pegging out for the duration of the command. For comparison I tried the same images on my fatso-desktop and it was taking almost 2 seconds to run, which is an absurd amount of CPU time for what I'm trying to accomplish.

I got the bright idea that I could generate thumbnails and check how much those changed. This was easy enough and I generated matching 64x48 thumbnails and ran compare on those. The result was barely different, averaging about ~25 seconds. Further squashing to 6x4 pixel images did not speed up the process much, I was still getting ~25 seconds to run.

Could I have something mis-configured? Why is this operation so resource intensive and why doesn't the size of the image seem to matter? Is there an alternative way to figure out if two images have divulged more than a certain threshold? (The screenshot data is easier since a hard changed-pixel-count does the trick, but the video data has static and needs fuzzy processing to figure out a difference number.)

  • Isn't it what motion is for? – Stéphane Chazelas Oct 23 '14 at 16:25
  • 3
    Not an answer, but apt-cache search image compare gives several alternatives including findimagedupes, perceptualdiff, and openimageio-tools. Also, as I found out the other day while writing a tag description, there is motion which sounds like what you're trying to reimplement... – derobert Oct 23 '14 at 16:25
  • @StéphaneChazelas Maybe it is (I wasn't aware of that project) but can I feed motion arbitrary static image frames as opposed to a direct video feed and and still have it do its job? My morbid curiosity also wants to know exactly what could hog 25 seconds of CPU cycles across 4 cores analyzing a pair of images with a grand total of 48 pixels between them (6x4*2). – Caleb Oct 24 '14 at 19:23
  • I quickly made two images, i.stack.imgur.com/KQiJX.png and i.stack.imgur.com/fWwyu.png. time compare -metric PHASH a.png b.png null: on my machine takes 0.01s. Curious about yours taking ~25s... – derobert Oct 28 '14 at 15:21
  • 1
    Adding -fuzz to compare when desired result is a metric doesn't make a difference. -fuzz is only effective when creating a "delta" image for visualizing differences. – Kurt Pfeifle Jan 31 '15 at 16:49
2

It is not a problem of the S/W, and it does not appear to be a problem with the Atom. I have an Atom 330 as my main machine (D945GCLF2), running Arch Linux - and I just did this test:

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

So the time it takes to compare two 640x400 images on an Atom330 is 1 sec - far faster than your 25 seconds.

In the absence of an strace -f log output from your run, the only thing I can guess is... bad hardware (maybe a passively cooled CPU that downthrottles its speed to avoid catching fire?) or badly compiled binaries (e.g. not using MMX/SSE extensions).

BTW, to make sure the kernel isn't down-throttling you, do this first (as root):

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

I would then try to monitor the CPU's temperature/frequency during the test - I am guessing it downthrottles to oblivion...

For completeness sake, these are the kernel and compare's versions I used in the test above:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.