0

I would like to create a hotfolder for my motion camera, into which I can drop images marking areas, which should be excluded in motion recognition via a *pgm mask. On these images, there is a small area marked with a transparent box with a magenta colored outline. My aim is to replace this box and outline with a black solid box and the rest of the image with white. (Tried to post samples here, but not enough reputation to do so.)

I know how to do this "by foot" using gimp, but I cannot figure out a clever and simple way achieving this with imagemagick.

I tried googling for solutions with -trim and -virtual-pixel, but no luck. Any help would be appreciated.

1 Answers1

0

I'll do this step-by-step so you can see the intermediate parts in case you are on Windows and bash doesn't work.

First, let's make make everything that is not within 10% of your magenta colour, namely rgb(225,75,130), into lime green:

magick source.jpg -fill lime -fuzz 10% +opaque "rgb(225,75,130)" result.png  

enter image description here

Ok, now let's get the trim box - i.e. all the constant junk that ImageMagick could trim off to focus on the magenta bit.

magick source.jpg -fill black -fuzz 10% +opaque "rgb(225,75,130)" -format '%@' info:
14x66+426+118

So your magenta box is 14x66pixels and located at offset 426,118 from the top-left. Now we want to get those in bash variables w,h,x,y. We need to change x and + into spaces using tr:

read w h x y < <(magick source.jpg -fill black -fuzz 10% +opaque "rgb(225,75,130)" -format '%@' info: | tr 'x+' '  ')

If we print this we get:

echo $w, $h, $x, $y
14, 66, 426, 118

Now we want to draw a rectangle, but that needs top-left and bottom-right, so we need to do some maths:

((x1=x+w))
((y1=y+h))

Ok, now we can load the original image, make it fully white, then draw our black rectangle:

magick source.jpg -threshold -1 -fill black -draw "rectangle $x,$y $x1,$y1" -depth 8 mask.pgm

So, the whole thing boils down to:

#!/bin/bash

read w h x y < <(magick source.jpg -fill black -fuzz 10% +opaque "rgb(225,75,130)" -format '%@' info: | tr 'x+' '  ')
echo $w, $h, $x, $y
((x1=x+w))
((y1=y+h))
magick source.jpg -threshold -1 -fill black -draw "rectangle $x,$y $x1,$y1" -depth 8 mask.pgm

There are other (maybe more elegant) ways of doing it, using flood-fills and/or connected components but I didn't want it to rely on your magenta box being "watertight", i.e. not rely on the sides being continuous and complete.

Also, if the size of your images is known and constant, you can avoid reloading the original and making it white by thresholding like I do in the last line and just create a canvas of the known dimensions, i.e.:

magick -size ${W}x${H} xc:white -fill black -draw "rectangle $x,$y $x1,$y1" -depth 8 mask.pgm
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432