Search code examples
imageimage-processingimagemagickedge-detectioncanny-operator

Finding shapes in an image using ImageMagick


I have two source images: first source image second source image

They seem equivalent, however, they are slightly shifted. Thus I created a diff image where the difference from each image is color coded (green and red).

diff image

I created it like this:

convert first.png second.png                      \
   \( -clone 0,1 -compose difference -composite   \
      -threshold 0 \)                             \
   \( -clone 0 -clone 2 -compose minus -composite \
      -threshold 0 -fill green1 -opaque white     \
      -channel rgba -fill none -opaque black \)   \
   \( -clone 1 -clone 2 -compose minus -composite \
      -threshold 0 -fill red -opaque white        \
      -channel rgba -fill none -opaque black \)   \
   \( -clone 0,1 -evaluate-sequence mean \)       \
   -delete 0-2      \
   -reverse         \
   -background none \
   -compose over    \
   -flatten         \
    multicolor_difference.png

as suggested here:

http://www.imagemagick.org/discourse-server/viewtopic.php?t=26105

Now I want to have the positions of the different green and red rectangles so that I have a list of shapes that I can work with in a code.

If I convert the image to text

# ImageMagick pixel enumeration: 2880,1370,255,srgb
0,0: (0,255,0)  #00FF00  lime
1,0: (0,255,0)  #00FF00  lime
2,0: (255,255,255)  #FFFFFF  white
3,0: (255,255,255)  #FFFFFF  white

and iterate over every pixel checking if the color is greenish oder red it's of course a performance killer.

Is there a better way to search in an image for certain shapes? Even checking for the occurrences of a certain color would be a great improvement. The output should be text so that I can interpret it in the code.

So all in all I want a description of the difference of two images in text form. In the best case I only have like 10 outputs for every rectangle.


Solution

  • I am not sure I understand your question, but think I can maybe get you close to an answer!

    I would maybe generate your green and red files separately, but let's start with what you have got. If you convert your red and lime difference file to a black and white PBM file you can pass it to potrace which will make it into a vectorised SVG file which you can maybe parse:

    convert difference.png    \
       -fill black            \
       +opaque lime           \
       -colorspace gray       \
       -threshold 1% pbm:- | potrace - -s -o green.svg
    

    which gives this:

    <?xml version="1.0" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
     "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
    <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
     width="2880.000000pt" height="1370.000000pt" viewBox="0 0 2880.000000 1370.000000"
     preserveAspectRatio="xMidYMid meet">
    <metadata>
    Created by potrace 1.12, written by Peter Selinger 2001-2015
    </metadata>
    <g transform="translate(0.000000,1370.000000) scale(0.100000,-0.100000)"
    fill="#000000" stroke="none">
    <path d="M20 6875 l0 -6826 25 -24 24 -25 14366 0 14365 0 0 6850 0 6850
    -14390 0 -14390 0 0 -6825z m7280 4505 l0 -160 7110 0 7110 0 0 -1180 0 -1180
    -7110 0 -7110 0 0 -160 0 -160 4290 0 4290 0 0 -1780 0 -1780 2820 0 2820 0 0
    -120 0 -120 -2830 0 -2830 0 0 1450 0 1450 -4270 0 -4270 0 0 -1320 0 -1320
    4260 0 4260 0 0 -120 0 -120 -4270 0 -4270 0 0 1810 c0 1200 3 1810 10 1810 6
    0 10 -37 10 -90 l0 -90 4270 0 4270 0 0 160 0 160 -4270 0 -4270 0 0 -60 c0
    -53 -2 -60 -20 -60 -20 0 -20 7 -20 1570 0 1040 3 1570 10 1570 6 0 10 -60 10
    -160z m8240 -4440 l0 -380 -3950 0 -3950 0 0 380 0 380 3950 0 3950 0 0 -380z
    m-2260 -1160 l0 -460 -1700 0 -1700 0 0 460 0 460 1700 0 1700 0 0 -460z
    m15505 -5759 c-3 -6 -11 -11 -16 -11 -5 0 -4 6 3 14 14 16 24 13 13 -3z"/>
    <path d="M7400 10040 l0 -1080 7010 0 7010 0 0 1080 0 1080 -7010 0 -7010 0 0
    -1080z"/>
    <path d="M7420 7920 l0 -180 4170 0 4170 0 0 180 0 180 -4170 0 -4170 0 0
    -180z"/>
    <path d="M7680 6940 l0 -340 3910 0 3910 0 0 340 0 340 -3910 0 -3910 0 0
    -340z"/>
    <path d="M9980 5780 l0 -360 1600 0 1600 0 0 360 0 360 -1600 0 -1600 0 0
    -360z"/>
    </g>
    </svg>