opencvimage-processingcomputer-visionimagemagickcrop

How to crop rectangles surrounded by black without know the coordinates?


I have the image below with almost all background in black. enter image description here Is there a way to crop rectangles surrounded by black without know the coordinates, were:

  1. height > 400px
  2. height about 144px
  3. height about 40px

I'm not interested in the blue rectangle (were height is about 45px) that is above each big rectangle. enter image description here I'd like to store the cropped rectangles in memory in order to make further processing with them. So for this input image would be 4 images stored in memory like below. Thanks in advance for any help.

Image 1:

enter image description here

Image 2

enter image description here

Image 3:

enter image description here

Image 4:

enter image description here

UPDATE2

I understand why the output is different for me. I tried your script with my actual input image (see below), that has gray background, and your script takes as input the black background image I show as input in this question. I've shown the black background image because I made some attempts previously to get my goal with imagemagick in bash.

enter image description here


Solution

  • I can do the following in Imagemagick 7 to get each non-black-containing regions using connected components filtering.

    Threshold. Then get any region larger than 20000 pixels in area. Then keep only the white ones, i.e. gray(255). Then print only the bounding boxes of the regions. Then loop over each region and filter on height an also on standard deviation (to discard near constant regions). Then crop those regions that pass.

    cropboxArr=(`magick charts.png -alpha off \
    -threshold 1% -type bilevel \
    -define connected-components:area-threshold=20000 \
    -define connected-components:mean-color=true \
    -define connected-components:exclude-header=true \
    -define connected-components:verbose=true \
    -connected-components 8 cleaned.png | grep "gray(255)" | awk '{print $2}'`)
    num=${#cropboxArr[*]}
    echo $num
    for ((i=0; i<num; i++)); do
    cropbox=${cropboxArr[$i]}
    echo "$i; $cropbox;"
    ww=`echo $cropbox | tr "x" "+" | cut -d+ -f1`
    hh=`echo $cropbox | tr "x" "+" | cut -d+ -f2`
    xo=`echo $cropbox | tr "x" "+" | cut -d+ -f3`
    yo=`echo $cropbox | tr "x" "+" | cut -d+ -f4`
    if [ $hh -gt 40 ]; then
    magick charts.png -alpha off -crop $cropbox +repage tmp.png
    std=`magick tmp.png -format "%[fx:standard_deviation]" info:`
    std_test=`magick xc: -format "%[fx:($std>0.1)?1:0]" info:`
    echo "$std; $std_test"
    echo ""
    if [ $std_test = 1 ]; then
    mv tmp.png charts_$i.png
    fi
    fi
    done
    

    Resulting Crops:

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    ADDITION

    Here is an alternate that get the full rows of regions.

    ht_thresh=40
    cropboxArr=(`im7 magick charts.png -set option:area "%[fx:w*$ht_thresh]" -alpha off \
    -threshold 1% \
    -scale 1x! \
    -threshold 25% -type bilevel \
    -define connected-components:area-threshold="%[area]" \
    -define connected-components:mean-color=true \
    -define connected-components:exclude-header=true \
    -define connected-components:verbose=true \
    -connected-components 8 cleaned.png | grep "gray(255)" | awk '{print $2}'`)
    num=${#cropboxArr[*]}
    echo $num
    for ((i=0; i<num; i++)); do
    cropbox=${cropboxArr[$i]}
    echo "$i; $cropbox;"
    ww=`echo $cropbox | tr "x" "+" | cut -d+ -f1`
    hh=`echo $cropbox | tr "x" "+" | cut -d+ -f2`
    xo=`echo $cropbox | tr "x" "+" | cut -d+ -f3`
    yo=`echo $cropbox | tr "x" "+" | cut -d+ -f4`
    if [ $hh -gt $ht_thresh ]; then
    im7 magick charts.png -alpha off -crop "%wx$hh+$xo+$yo" +repage -trim +repage tmp.png
    std=`im7 magick tmp.png -format "%[fx:standard_deviation]" info:`
    std_test=`im7 magick xc: -format "%[fx:($std>0.13)?1:0]" info:`
    echo "$std; $std_test"
    echo ""
    if [ $std_test = 1 ]; then
    mv tmp.png charts_$i.png
    fi
    fi
    done
    

    Results:

    enter image description here

    enter image description here

    enter image description here

    enter image description here