I have the image below with almost all background in black. Is there a way to crop rectangles surrounded by black without know the coordinates, were:
I'm not interested in the blue rectangle (were height is about 45px) that is above each big rectangle. 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:
Image 2
Image 3:
Image 4:
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.
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:
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: