TransWikia.com

Finding the position of the lowest all-white line

Stack Overflow Asked on December 20, 2021

How to find the position of the lowest all-white line in the upper half of the image (marked in red) ?
How to find the position of the highest all-white line in the lower half of the image (marked in blue) ?

Alternatively, how to find a bounding box of the "grid area" ?
I would like to use the coordinates of this bounding box to define a -region for subsequent operations (e.g. for color replacements), so I would appreciate a hint how to set this region to the position and size of this bounding box.

Annotated Input Image

Raw input image:
Raw input image

The background color is dependably white rgb(255,255,255).
The image size is constant.
The vertical position and height of the "grid area" is variable.
The "grid area" always contains non-white pixels.

EDIT:
This code outputs the coordinates of these red & blue lines in its textual output:

magick input.png -alpha off 
-threshold 99.6%% 
-statistic minimum "%%[fx:int(w/255)]x1"  
-scale 1x! 
-threshold 99.6%% 
-define connected-components:verbose=true 
-define connected-components:exclude-header=true 
-connected-components 4 result.png

However, I have no idea how to cause -connected-components to list only the first object with the largest area (which contains the sought coordinates) or how to use this object as aregion in subsequent ImageMagick operations.

One Answer

Here is one way to get the bounding box of the table in Unix syntax ImageMagick (on my Mac). If you want the white above and below the bounding box, then subtract one from the top and add one to the bottom coordinates.

  • Read the image, turn alpha off, threshold and invert (negate) so the lines are white on black background
  • Make a copy (clone) and apply horizontal morphology to fill in gaps in the horizontal lines
  • Make another copy (clone) and apply vertical morphology to fill in gaps in the vertical lines without causing the text at the top to merge with the outer lines.
  • Delete the original
  • Combine the horizontal and vertical lines
  • Apply connected components processing, filtering on area so that only the largest two areas remain as a white rectangle on the black background (with one black cutout that does not matter for getting the bounds of the white rectangle)
  • Extract the bounding box (WxH+X+Y)
  • From the bounding box, extract the top=Y and the bottom=(Y+H-1)

I have saved some temporary images to show you the steps.

bbox=`convert table.png -alpha off -threshold 10% -negate +write tmp0.png 
( -clone 0 -virtual-pixel black -morphology close rectangle:25x1 +write tmp1.png ) 
( -clone 0 -virtual-pixel black -morphology close rectangle:1x10 +write tmp2.png ) 
-delete 0 
-compose plus -composite -type bilevel +write tmp3.png 
-define connected-components:verbose=true 
-define connected-components:exclude-header=true 
-define connected-components:area-threshold=20000 
-define connected-components:mean-color=true 
-connected-components 8 
tmp4.png | grep "gray(255)" | awk '{print $2}'`
echo "$bbox"
bbox=`echo $bbox | tr "x" "+"`
top=`echo $bbox | cut -d+ -f3`
height=`echo $bbox | cut -d+ -f2`
bottom=$((top+height-1))
echo "top=$top bottom=$bottom"

Negated threshold (tmp0)

enter image description here

Horizontal gaps filled image (tmp1)

enter image description here

Vertical gaps (mostly) filled image (tmp2):

enter image description here

Combined horizontal and vertical images (tmp3) (All but one of the gaps around the bounding (outside) lines are filled (the inside ones do not matter):

enter image description here

Connected Components area filtered image:

enter image description here

Textual Information Output (first line is bbox=WxH+X+Y):

1258x762+11+141
top=11 bottom=772

Here is an alternate method.

convert table.png -alpha off -threshold 10% -negate +write tmp0.png 
( -clone 0 -virtual-pixel black -morphology close rectangle:25x1 +write tmp1.png ) 
( -clone 0 -virtual-pixel black -morphology close rectangle:1x10 +write tmp2.png ) 
-delete 0 
-compose plus -composite -type bilevel +write tmp3.png 
-define connected-components:verbose=true 
-define connected-components:exclude-header=true 
-define connected-components:area-threshold=20000 
-define connected-components:mean-color=true 
-connected-components 8 tmp4.png

convert tmp4.png -format "%@n" info: | head -n 1
echo "$bbox"
bbox=`echo $bbox | tr "x" "+"`
top=`echo $bbox | cut -d+ -f3`
height=`echo $bbox | cut -d+ -f2`
bottom=$((top+height-1))
echo "top=$top bottom=$bottom"

Answered by fmw42 on December 20, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP