Compare images, detect movement

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
benjay

Compare images, detect movement

Post by benjay »

Hi

I'm trying to detect movements in a video stream by comparing its extracted images (1 frame per second).

Here is my approach:
Because I don't want to compare the whole image, I extract 9 parts evenly placed throughout the image (16x16 pixels per part).

Code: Select all

convert -extract image1.png crops/16x16+120+64/image1.png
Then I calculate the mean for every part like so

Code: Select all

convert imageY_partXY.png -colorspace rgb -scale 1x1 -format "%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)]" info:
Next I calculate the distance for every part by using the euclidean distance (image1_part1 <-> image2_part1, image2_part1 <-> image3_part1, and so on ...)
If the distance is below a given threshold (which needs to be defined) then I assume that there is no movement for this particular part.
If all the parts have no movement, then I reckon the compared images to be the same. After 5 (just an assumption!) images I assume the stream has no movement.

I know, I could also do it this way:

Code: Select all

compare image1.png image2.png image_out.png
But since the colors are never exactly the same I need to add some tolerance.

Code: Select all

compare -fuzz 5% image1.png image2.png image_out.png
and then look at the difference.

But I use IM just for prototyping and I need to find a way so it works without IM and that its fast enough.
This solution works kind of. Of course it does not recognize every movement because it just covers those 9 parts.

Does anyone have a better approach? Or any idea to improve it?
Is it a good idea to use mean to compare the parts?

Feedback is very appreciated :)
lwhistler
Posts: 23
Joined: 2010-09-15T15:33:29-07:00
Authentication code: 8675308

Re: Compare images, detect movement

Post by lwhistler »

benjay wrote:But I use IM just for prototyping and I need to find a way so it works without IM and that its fast enough.
I don't understand this statement. You do not want to use IM? And what is fast enough? Can you be more specific.

-----------------------------------------

I had some fun with this and my solution is to generate a gray-scale mask of the changed pixels in all images to a reference image. The masks of identical images would be black and have a smaller file size than the masks of images that differ. I then would delete all masks smaller than an x amount of pixels and the remaining masks would be matched up with the original images through similar file names. Those image files are different than the reference image, perhaps because of movement.
  • Below is a bash script that accomplishes all of the above with one click, tested on JPG's but should work with PNG's.
  • Place JPG's in folder and enter a REFERENCE_IMAGE image.
  • Determine BLACK_MASK_SIZE for similar images, in my case it was below 70000
  • Click shell script file to run.
  • It will write all mask file sizes to a log file. The masks for similar images to the reference image will all be the same small sizes, since they are black.
Save as an executable .sh file and just click to activate.

Code: Select all

#!/bin/bash
COUNTER=1
REFERENCE_IMAGE=one.jpg
BLACK_MASK_SIZE=70000

for image_file in *.jpg
do
counter=`printf %06d $COUNTER`
compare $REFERENCE_IMAGE $image_file -compose Src -highlight-color White -lowlight-color Black temp_$image_file
let COUNTER=COUNTER+1
done


for temp_file in temp*.jpg
do
filesize=$(stat -c%s "$temp_file")
echo "$temp_file filesize: $filesize" >> log.txt

if [ $filesize -lt $BLACK_MASK_SIZE ]; then
rm $temp_file
fi
done

Check out:

http://www.imagemagick.org/Usage/compare/



-----------
Post Reply