Search code examples
imagemagick

How to cover area while cropping rectangles with ImageMagick 7?


I'm stuck in how to remove (paint in white) the parts at the top of the image1 that says Show legend, Trend Chart and the 3 small lines. I have a loop that crops several rectangles previously and would like to remove that areas while cropping each rectangle if possible.

The loop to crop in previous process is like this and I'd like to add the option that removes the areas mentioned above during this for loop if possible.

for ((i=0; i<$num; i++)); do
    convert $input_image -write mpr:img +delete mpr:img -crop "${coordinates[$i]}" rectangle$i.png 
done

Image1.1 enter image description here

Image1.2 enter image description here

  • Using IM7 under Cygwin (Linux emulator)

I was thinking in create a 896x80 rectangle like Image2 with a part transparent and the other in white to overlap over Image1

Image2 enter image description here

Basically is remove the parts within red line in left side of Image3 to get the right side of Image3

Image3 enter image description here

UPDATE

I've compared this small bars image with Image1.1 and this is the result:

small bar.png image

enter image description here

$ magick compare -metric RMSE bar.png image1.1.png compare.png
10083.5 (0.153865)

$ magick compare -metric RMSE image1.1.png bar.png compare.png
8732.61 (0.133251)

UPDATE2

This is the whole magick version print:

$ magick -version
Version: ImageMagick 7.1.1-24 Q16-HDRI x86_64 21856 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5)
Delegates (built-in): bzlib djvu fontconfig freetype jbig jng jp2 jpeg lcms lqr lzma openexr png tiff x xml zlib
Compiler: gcc (11.4)

Solution

  • Here is how to process your images in Imagemagick once they have been cropped.

    Input:

    enter image description here

    or

    enter image description here

    Bar Image:

    enter image description here

    crop_image="chart1.png"   # or use "chart2.png"
    data=`magick compare -metric ncc -subimage-search \( $crop_image +repage \) bars.png null: 2>&1`
    yloc=`echo "$data" | cut -d@ -f2 | cut -d, -f2`
    echo $yloc
    if [ $yloc -lt 40 ]; then
    magick $crop_image \
    \( -size 140x40 xc:white \) -geometry +0+0 -composite \
    ${crop_image}_whitened.png
    else
    magick $crop_image \
    \( -size 140x40 xc:white \) -geometry +0+0 -composite \
    \( -size 150x40 xc:white \) -geometry +740+0 -composite \
    ${crop_image}_whitened.png
    fi
    

    Result for first image:

    enter image description here

    Result for second image:

    enter image description here

    You can start with the large multi-chart image and do the crop for any given chart in the loop, if you want.

    ADDITION

    Here is a timing of the top part on my Mac using -metric ncc.

    crop_image="chart1.png"   # or use "chart2.png"
    time data=`magick compare -metric ncc -subimage-search \( $crop_image +repage \) bars.png null: 2>&1`
    yloc=`echo "$data" | cut -d@ -f2 | cut -d, -f2`
    echo $yloc
    46
    
    real    0m0.682s
    user    0m0.426s
    sys 0m0.129s
    

    So the result is 46 for the first image and it took 0.682 seconds to process with -metric ncc.

    If I use -metric rmse, it will take much longer.

    crop_image="chart1.png"   # or use "chart2.png"
    time data=`magick compare -metric rmse -subimage-search \( $crop_image +repage \) bars.png null: 2>&1`
    yloc=`echo "$data" | cut -d@ -f2 | cut -d, -f2`
    echo $yloc
    46
    
    real    0m8.038s
    user    0m7.791s
    sys 0m0.131s
    

    Same result of 46, but it took 8.038 seconds.