Page 1 of 1

Finding image within image

Posted: 2011-07-15T17:30:43-07:00
by jdnet
I'm trying to find a way to replace all instances of a particular pattern within my images, inserting a different pattern wherever the first pattern is found. For example, if I wanted to replace all instances of the letter "A" in an image consisting of text and insert the letter "B" each time instead, how would I go about this? Both "A" and "B" can be saved as their own tiny image... can I search for the tiny "A" image within all of my larger images, and overlay the tiny "B" image on top of it each time it is found?

Re: Finding image within image

Posted: 2011-07-15T17:52:21-07:00
by fmw42
If there is no rotation involved, you can easily find the best match of a small image in a larger image. The compare function does this.

compare -metric rmse -subimage-search largeimage smallimage outputimages

where outputimages will be either one image with two layers (if tif or gif) or two images with -0 and -1 appended to the same filename (if png)

The second of these images is the match score image. The brightest spot(s) correspond to the best matches. The function also reports the location and score value for the brightest result in that image. These locations correspond to the upper left corner of where the smaller images can be found in the larger image.

If you need more than one match in the image, you will need to threshold the image and return the location of every white pixel, skipping every black pixels. Then you have to get the centers of those regions. (see the two comments at the end of the post listed below).

If you come up with a good technique for getting multiple matches, please let us know.

A simple example is at:
viewtopic.php?f=1&t=14613&p=51076&hilit ... ric#p51076

Since then the syntax has changed so that -subimage-match is required to be added to inform IM that it is not a match between two same size images (simple explanation).

see
http://www.imagemagick.org/script/compare.php
http://www.imagemagick.org/Usage/compare/

Replacing the letter A with the letter B would assume that B is as large or larger than A and then compositing the B image at each location found. See http://www.imagemagick.org/Usage/layers/ (especially -flatten or -layers merge)

Re: Finding image within image

Posted: 2011-07-15T18:45:16-07:00
by jdnet
Thanks, fmw42. I'm a little confused about one part. Is imagemagick going to save the results from the compare operation in a log file somewhere, or in a variable... or how do I grab the location values to turn around and use them afterward?

Re: Finding image within image

Posted: 2011-07-15T19:07:52-07:00
by fmw42
jdnet wrote:Thanks, fmw42. I'm a little confused about one part. Is imagemagick going to save the results from the compare operation in a log file somewhere, or in a variable... or how do I grab the location values to turn around and use them afterward?

It normally goes to the terminal as standard error. But you can put it in a variable as follows in unix:

result=$(compare -metric rmse -subimage-search mandril3.png mandril3_156_22.png mandril3_similarity.png 2>&1)

or

result=`compare -metric rmse -subimage-search mandril3.png mandril3_156_22.png mandril3_similarity.png 2>&1`

Then you need to use other unix commands (sed and cut) to parse the score and the coordinates from the variable.


score=`echo $result | sed 's/ //g' | cut -d\@ -f1`
coords=`echo $result | sed 's/ //g' | cut -d\@ -f2`
x=`echo $coords | cut -d, -f1`
y=`echo $coords | cut -d, -f2`

If you are on windows, then you need to read the following about differences in syntax and scripting:
http://www.imagemagick.org/Usage/windows/

P.S. NOTE: subimage compare is not fast. If on unix, you can speed it up using my FFT processing script, normcrosscor, see the link below.