Search code examples
imagemagick

imagemagick - return the bounding box of each contiguous object


How do you use imagemagick to return the bounding box coordinates of each object identified in the image?

enter image description here


Solution

  • You can do that in Imagemagick using connected components processing. The following is Unix syntax for Imagemagick 6

    Read the input. Then threshold and add some padding. Then apply morphology close to close up some disconnected regions that should connect (especially the bone on the head) and shave off the padding. Then apply connected components processing.

    convert objects.jpg \
    -negate -threshold 15% -bordercolor black -border 10 \
    -morphology close disk:8 -type bilevel -shave 10x10 \
    -define connected-components:exclude-header=true \
    -define connected-components:mean-color=true \
    -define connected-components:area-threshold=100 \
    -define connected-components:verbose=true \
    -connected-components 8 null: | grep "gray(255)" | awk '{ print $2 }'
    

    Result Listed To Terminal Window:

    268x567+408+35
    212x379+185+48
    560x98+2+652
    75x434+36+5
    128x131+26+460
    128x130+231+498
    
    list="268x567+408+35
    212x379+185+48
    560x98+2+652
    75x434+36+5
    128x131+26+460
    128x130+231+498"
    convert objects.jpg tmp.png
    for item in $list; do
    ww=`echo "$item" | tr "x" "+" | cut -d+ -f1`
    hh=`echo "$item" | tr "x" "+" | cut -d+ -f2`
    xo=`echo "$item" | tr "x" "+" | cut -d+ -f3`
    yo=`echo "$item" | tr "x" "+" | cut -d+ -f4`
    x1=$xo
    y1=$yo
    x2=$((x1+ww))
    y2=$((y1+hh))
    convert tmp.png -fill none -stroke red \
    -draw "rectangle $x1,$y1 $x2,$y2" -alpha off tmp.png
    done
    convert tmp.png objects_bboxes.jpg
    rm -f tmp.png
    

    enter image description here