Page 1 of 2

Locate subimage

Posted: 2016-05-30T11:01:54-07:00
by VanGog
I tried this command taken from here http://www.imagemagick.org/Usage/compare
however in Windows batch (CMD) it produces error:

Code: Select all

convert large_image.png small_image.png miff:- |
      compare -metric RMSE -subimage-search - miff:- |
        convert - -delete 0 -grayscale 
Why there are the pipe-lines? If I omit them so binary code it posted to display device. What should it do? Looks like this does not work on windows, does it?

Re: Locate subimage

Posted: 2016-05-30T11:29:06-07:00
by fmw42
You have no new line escapes at the end of your lines and no output for the last command. On windows try

Code: Select all

convert large_image.png small_image.png miff:- |^
compare -metric RMSE -subimage-search - miff:- |^
convert - -delete 0 -grayscale rec601luma result.png
EDITED above -- snibgo is correct, -grayscale needs a method.


But why the need for the multiple commands? Just do

Code: Select all

compare -metric RMSE -subimage-search large_image.png small_image.png result.png
You will get two images. result_0.png and result_1.png. If you want you can ignore result_0.png and just look at result_1.png. It should be grayscale

see for example viewtopic.php?f=1&t=14613&p=51076&hilit ... ric#p51076 (but note at the time of that post -subimage-search was not needed. it is for current versions of IM)

Please always provide your IM version and platform when asking questions on this forum, since syntax may differ.

Re: Locate subimage

Posted: 2016-05-30T11:50:11-07:00
by snibgo
... and "-grayscale" needs a method.

Re: Locate subimage

Posted: 2016-05-30T12:15:07-07:00
by VanGog

Code: Select all

convert highway_mask.png small_img_board_1.png miff:- |^
      compare -metric RMSE -subimage-search - miff:- |^
      convert - -delete 0 -grayscale
CMD says: file not found


Code: Select all

convert highway_mask.png small_img_board_1.png miff:-   |       compare -metric RMSE -subimage-search - miff:-   |       convert - -delete 0 -grayscale
  není názvem vnitřního ani vnějšího příkazu,
spustitelného programu nebo dávkového souboru.

convert -version
Version: ImageMagick 6.7.5-1 2012-01-28 Q8
Edit:
The original which I omited by incidend contains:

Code: Select all

MS show:
on the end. But including it gives same error

also note, both convert.exe and compare.exe is present and I can execute them

Re: Locate subimage

Posted: 2016-05-30T12:50:20-07:00
by fmw42
Try my simple command above. You are making it too complicated using that code. And as snibgo said -grayscale needs a method and as I said above, you have no output image. Thus it says file not found since it needs an output.

Note I have edited my comments earlier to put in the -grayscale method. Thanks snibgo, I overlooked that.

On my Mac, it works fine as:

Code: Select all

convert mandril3.jpg mandril3_156_22.jpg miff:- |\
compare -metric RMSE -subimage-search - miff:- |\
convert - -delete 0 -grayscale rec601luma result.png
2633.32 (0.0401819) @ 156,22

The -grayscale and method is not really needed since the second output image (the correlation surface) is already grayscale.

Where did you find this command? It is overkill.

Re: Locate subimage

Posted: 2016-05-30T13:01:32-07:00
by VanGog
I used output image too but that is strage. It still gave that error. That is not error of IM but of the system file not found

Re: Locate subimage

Posted: 2016-05-30T13:03:24-07:00
by fmw42
Try my simpler command and lets see if it works. Why do you want the more complicated command? It is overkill.

Code: Select all

compare -metric RMSE -subimage-search large_image.png small_image.png result.png
Does this exact command work?

Code: Select all

convert large_image.png small_image.png miff:- |^
compare -metric RMSE -subimage-search - miff:- |^
convert - -delete 0 -grayscale rec601luma result.png
Put in your exact images and then paste your version of the command back here and the error message if it does not work.

I think IM 6.7.5.1 is too old to know about -grayscale. I think that was only available for 6.8.3-10. Try removing it

So try

Code: Select all

compare -metric RMSE -subimage-search large_image.png small_image.png result.png
and

Code: Select all

convert large_image.png small_image.png miff:- |^
compare -metric RMSE -subimage-search - miff:- |^
convert - -delete 0 result.png

Re: Locate subimage

Posted: 2016-05-30T13:53:07-07:00
by VanGog
Yes it works. I am waiting for result coz it takes long... 55 seconds for 1024x768px

This way it seems too much complicated. If I want to find blue rectangles on the map here:
https://3.bp.blogspot.com/-v3-vlgXO0A4/ ... 0/test.png
I could try to search just three top lines of the image
https://4.bp.blogspot.com/-_EDGYv_YQ40/ ... 0/test.png
either just shape or exactly these three colors and I could then get the result faster?

If I would write program to search rectangle I would just search for the color difference between white and blue to find edge in first line, then I woudld search next white pixels and finally if the given count of white pixel is found and the next one is black then I have found the result at first line. But it seems to me that this way it processed much redundant stuff.

Or maybe to resize the image and the sub image to 25% and then search
https://4.bp.blogspot.com/-gNocu9gcR6g/ ... blue_2.png

the result to get approximate location ... then search the original image using mask

Image

This taken just few seconds. After levels I have this:

Image

And after resize to original dimensions I have:
Image

That looks good.

It still does not contain the exact mask, but I know the location now.

Re: Locate subimage

Posted: 2016-05-31T04:10:19-07:00
by VanGog
I have written this batch file for Windows:

Code: Select all

@ECHO OFF
cls
ECHO ON
REM To reduce processing time 18x I scale the image
      
REM 2.5s when I resized both images down at 25% of original dimensions                                        

REM get original size of large image
for /f "usebackq tokens=1" %%o in (`convert map.png -format "%%wx%%h" info:`) do (
  set original_size_1=%%o )
echo %original_size_1% 

convert map.png -format "%%wx%%h" info:
@REM Scale map down
convert map.png -scale 25%% map_scaled.png
@REM generate mask mask3-1.png
compare -metric RMSE -subimage-search map_scaled.png sub_image_blue_2.png mask3.png
@REM Apply level(s) on mask
convert mask3-1.png -level 75%%,50%% mask_map_level_75_50_scaled.png
@REM Restore mask to original size
convert mask_map_level_75_50_scaled.png -resize %original_size_1% mask_map_locations.png
Why when I resize the mask back to original size, the result dimensions in mask_map_locations.png are 1021x632 instead 1024x632? I tried to set 1024x362 but -scale nor -resize does not allow that.

Re: Locate subimage

Posted: 2016-05-31T04:28:05-07:00
by snibgo
To resize to an exact size, use ! suffix, eg "-resize 1024x362!" Without "!", it will retain the aspect ratio.

There are many methods for doing fast searching. My "Searching an image" page gives a general technique for arbitrary images (with Windows BAT script).

If the nature of the subimage is simple and constant, eg a blue rectangle, optimisation should be simple.

Re: Locate subimage

Posted: 2016-05-31T04:47:45-07:00
by VanGog
Please if you know more techniques for searching sub-images VERY fast gimme some examples. I need to work with big images like high resolution image of map to find the sub image. This could take long so more examples with better performence are welcome. Also the problem of this techniq is that is finds only 1 sub image. I have two images of similar color: red and blue. It would be better if I could search for blue rectangle OR red rectangle during one interaction than 2 or more interactions.

Also I will need help how to place the mask of the rectangle into the locations found by subimage search. Something like in the example with end points detection where red circles are pasted into the ends.

PS:
I like the idea of scaling images down that is so cool and can save hours or days of time. This gives a possibility to search big subimages in image because when one scales them to 9x5 px than it happens very fast.

Re: Locate subimage

Posted: 2016-05-31T06:48:55-07:00
by VanGog
Now I have found your article Searching an image http://im.snibgo.com/srchimg.htm which is great because you write the scripts using Windows shell syntax. It will take some time to read it but now I am at this point:
"The script srchImg.bat does two or more searches. The first resizes the images before searching; the last uses the results of the previous to make a crop that will be searched."
Is it possible to search this way if you have found more results? Using a mask instead cropping would be solution.

Windows XP,
Version: ImageMagick 6.7.5-1 2012-01-28 Q8

Re: Locate subimage

Posted: 2016-05-31T09:11:37-07:00
by VanGog
Edit: Code for this post

Code: Select all

REM 2.5s when I resized both images down at 25% of original dimensions                                        

REM get original size of large image
for /f "usebackq tokens=1" %%o in (`convert map.png -format "%%wx%%h" info:`) do (
  set original_size=%%o )
echo %original_size% 

convert map.png -format "%%wx%%h" info:
@REM Scale map down
convert map.png -scale 25%% map_scaled.png
@REM generate mask mask4-1.png
compare -metric RMSE -subimage-search map_scaled.png sub_image_water.png mask4.png
@REM Apply level(s) on mask
convert mask4-1.png -level 75%%,50%% mask_map_level_75_50_scaled_water.png
@REM Restore mask to original size
convert mask_map_level_75_50_scaled_water.png -resize "%original_size%!" mask_map_locations_water.png
One more question.

When I checked the first image it did not capture all locations of blue rectangles:
Image
Does this mean it did not find accurate result? Even that the second file contains good and accurate results... Why I ask? Because now I did second test with light blue rectangle representing a water surface:

https://1.bp.blogspot.com/-q4UVCD8CFUg/ ... _water.png

And I got these weird results:
https://4.bp.blogspot.com/-voa_tZpnVJI/ ... ask3-0.png

Image
That is opposite to previous case. The first image found exact location whilst the second did not. The white areas which should mean the result are not water. When I blend the mask with map:
Image
So you see that the blackened areas are the main routes whilst white are streets, routes, green and built-up areas. Why this happened? I know the image had not boundaries of shape but in the case that there would exist a light blue rectangle on the image simultaneously with water, that it searches everything else, but not what I wanted...

Re: Locate subimage

Posted: 2016-05-31T17:15:03-07:00
by snibgo
My script srchImg.bat searches for a subimage within a large image.

Calling the script will return a single result. It won't return multiple results. It does contain facilities (siDELTEMPSRC etc) to reduce processing if a second search, with a different subimage, is done on the same large image. But if you want to find all the exact matches of a subimage within a large image, the script won't do that. It could be modified to do that. Or it could be called multiple times, changing the large image between calls to black-out the previous found result, but that would be very inefficient.

It speeds up processing when the sub-image is fairly large, eg 100x100 or larger. It gives no acceleration when the sub-image is less than 10x10.

As I explain on my page, it can theoretically find a match that isn't the best possible match, but I've never seen that happen in ordinary photographs.

Your sub_image_water.png is only 5x3 pixels, so is too small for srchImg.bat to be helpful.

Where zurich.png is your street map of Zurich, 1024x632 pixels:

Code: Select all

compare -metric RMSE -subimage-search zurich.png sub_image_water.png zurich_water.png
This takes about 14 seconds. zurich_water-1.png is:
Image

The best matches are shown in lighter tones. A perfect match would be white, but there are no perfect matches.

Your sub_image_water.png is almost a constant colour. We can find its mean colour, scale it to the same size as zurich.png, and find the difference:

Code: Select all

convert sub_image_water.png -scale 1x1! -scale 1024x632! zurich.png -compose Difference -composite -negate -grayscale Average zurich_water_2.png
I negate and grayscale for easy comparison. Again, near-white is water. This takes 0.12 seconds. We have improved performance by a factor of 100. It is also less blurred.

Image

If you want to find occurrences of a particular colour in a large image, "-composite" is very much quicker than "-subimage-search".

Re: Locate subimage

Posted: 2016-05-31T18:10:45-07:00
by fmw42
Minor point. He is using ImageMagick 6.7.5-1, which is too early for -grayscale. Replace -grayscale Average with -colorspace OHTA -channel red to get the average. I think that version is too old for -colorspace HSI -channel blue. See viewtopic.php?f=1&t=29799