Page 3 of 4

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-19T17:28:29-07:00
by fmw42
list="" #create an empty list
bboxArr=(`convert BW.jpeg -threshold 50% -type bilevel \ # threshold your BW.jpeg and set its type to bilevel
-define connected-components:verbose=true \ # define verbose mode for CCL
-define connected-components:area-threshold=2000 \ # define area threshold=2000 for CCL
-connected-components 4 \ # do CCL
null: | awk 'NR>2 {print $2}' | sort -g -t "+" -k 3,2`) # save to null: image, skip first two line, sort on y, then x
num="${#bboxArr[*]}" # compute the number of bounding boxes
j=0 # set j=0
list=" \( mpr:img -crop ${bboxArr[0]} +repage \) " # set the list to use mpr:img (see later) and crop for 0th bbox
yy=`echo "${bboxArr[0]}" | cut -d+ -f3` # extract y value from bbox 0 and store in yy
for ((i=1; i<num; i++)); do # loop over the number of bboxes
ynew=`echo "${bboxArr[$i]}" | cut -d+ -f3` # set ynew to the y value of bbox for the ith loop
test=`convert xc: -format "%[fx:abs($ynew-$yy)<=5?1:0]" info:` # test the difference
if [ $test -eq 1 ]; then #check if the difference is within 5 pixels
list="$list \( mpr:img -crop ${bboxArr[$i]} +repage \) " # if so add the mpr:img again and crop if for the ith bbox
else # else
count=`echo "$list" | wc -w` # get the count of words
if [ $count -eq 6 ]; then # if count is 6, then we have only one bbox
eval 'convert input.jpeg +write mpr:img +delete '$list' image$j.jpg' # so just do the actual crop after saving the input to mpr:img
else # otherwise (count not equal 6)
eval 'convert input.jpeg +write mpr:img +delete '$list' -background white +smush +15+0 image$j.jpg' # crop all the bboxes in the list and smush them to append
fi # end if
list=" \( mpr:img -crop ${bboxArr[$i]} +repage \) " # if test = 0 then we are starting a new set, so start the list again
ynew=$yy # set ynew to yy
yy=`echo "${bboxArr[$i]}" | cut -d+ -f3` # compute a new yy
j=$((j+1)) # increment j
fi # end if
done # end of loop
if [ $count -eq 6 -a $i -eq $num ]; then # check if count = 6 and i = num
eval 'convert input.jpeg +write mpr:img +delete '$list' image$j.jpg' # crop the last set which only has one bbox
elif [ $count -ne 6 -a $i -eq $num ]; then # else if count not equal 6 and i = num
eval 'convert input.jpeg +write mpr:img +delete '$list' -background white +smush +15+0 image$j.jpg' #then crop the last set which has more than one box
fi # end if

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-19T17:51:01-07:00
by cgkas
fmw42 wrote: 2018-10-19T17:10:44-07:00 My best guess is that your sort does not work the same as mine. Test this:

Code: Select all

convert BW.jpeg -threshold 50% -type bilevel \
-define connected-components:verbose=true \
-define connected-components:area-threshold=2000 \
-connected-components 4 \
null: | awk 'NR>2 {print $2}' | sort -g -t "+" -k 3,2
It should list this in the following order:

Code: Select all

264x40+680+109
423x145+530+203
423x145+70+203
422x205+70+379
423x205+530+379
422x355+70+589
423x355+530+589
I explained the logic above. If you have specific questions, then ask away.
It seems to be the order. I get a different list order.

Code: Select all

$ convert BW.jpeg -threshold 50% -type bilevel \
> -define connected-components:verbose=true \
> -define connected-components:area-threshold=2000 \
> -connected-components 4 \
> null: | awk 'NR>2 {print $2}' | sort -g -t "+" -k 3,2
264x40+680+109
422x205+70+379
422x355+70+589
423x145+530+203
423x145+70+203
423x205+530+379
423x355+530+589
I'll check the logic of your code and see if I'm abale to adapt it.

Thanks a lot fmw42 for your help, time, patience.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-19T18:52:10-07:00
by fmw42
I suspect your sort is not sorting. Check your sort command and see if it supports the same features. Test my short code above and see if you can modify the sort to give the same order.

The -g means compare according to general numerical value (not text order)

The -t is the field separator. I use the + sign to separate fields.

The -k is the order of fields to sort. So first on 3 which is y and then on 2 which is x. 1 is the WxH.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-19T19:02:34-07:00
by fmw42
Perhaps your sort does not know about -g. So try -n

convert BW.jpeg -threshold 50% -type bilevel \
-define connected-components:verbose=true \
-define connected-components:area-threshold=2000 \
-connected-components 4 \
null: | awk 'NR>2 {print $2}' | sort -n -t "+" -k 3,2

Code: Select all

264x40+680+109
423x145+530+203
423x145+70+203
422x205+70+379
423x205+530+379
422x355+70+589
423x355+530+589

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T00:51:32-07:00
by cgkas
fmw42 wrote: 2018-10-19T19:02:34-07:00 Perhaps your sort does not know about -g. So try -n

convert BW.jpeg -threshold 50% -type bilevel \
-define connected-components:verbose=true \
-define connected-components:area-threshold=2000 \
-connected-components 4 \
null: | awk 'NR>2 {print $2}' | sort -n -t "+" -k 3,2

Code: Select all

264x40+680+109
423x145+530+203
423x145+70+203
422x205+70+379
423x205+530+379
422x355+70+589
423x355+530+589
Hi fmw42.

Thanks for continue helping me.

I was able to fix the sort issue changing from

Code: Select all

sort -n -t "+" -k 3,2
to

Code: Select all

sort -t "+" -k3n -k2n
I only see one issue with the size of the boxes because I would like to get the coordinates of red boxes that are surrounded by the white line where heigth is 158 and 308, but and I'm getting the bigger ones (to the right in green), where height is 203 and 355.

Below an image of what I'm saying.
Image

Thanks again for the kind help.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T04:43:21-07:00
by snibgo
Running Fred's script on Cygwin bash on Windows 8.1, I get the same results as cgkas, not Fred.

The problem is in the sort, "-k 3,2". Sort with "--debug" says it can't find the key in any record. "sort --help" says:
-k, --key=KEYDEF

KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where F is a
field number and C a character position in the field; both are origin 1, and
the stop position defaults to the line's end.
I suppose that having a start position that is after the stop position isn't valid.

The workaround is to sort twice: first on x, than on y, and the sort on y must be "stable". So that line now looks like:

Code: Select all

 null: | awk 'NR>2 {print $2}' | sort -g -t "+" -k 2,2 | sort -s -g -t "+" -k 3,3`)
... and the result is as Fred showed.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T08:07:38-07:00
by cgkas
For me it works when I put sort in this way as mentioned in previous post.

Code: Select all

sort -t "+" -k3n -k2n
My only issue is in output the boxes that are been taken are bigger than those I would like to.

The output shows the size of green boxes and I would like the size of red boxes. Maybe you can help me to fix this.

Image

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T11:14:59-07:00
by fmw42
I edited my code to use -k 3,3 -k 2,2 (also -k 3 -k 2 works). This produces the same results for me as with -k 3,2. Use whatever works. Thanks snibgo for looking into that on your Cygwin.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T11:24:37-07:00
by snibgo
I had overlooked Fred's previous example showing multiple "-k" entries. This is how we can sort by field 3 (y) then field 2 (x), and this is cleaner than calling sort twice, so my script now has:

Code: Select all

 null: | awk 'NR>2 {print $2}' | sort -g -t "+" -k 3 -k 2`)
... and this works fine.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T12:03:40-07:00
by fmw42
snibgo, I changed the code after reading your reply and cgkas reply as I mentioned just above your last post here. I think that also is cleaner code.

Here is are examples from a Google search:

https://unix.stackexchange.com/question ... umns/78926
https://stackoverflow.com/questions/357 ... -unix-sort
https://en.wikipedia.org/wiki/Sort_(Unix)

In bash, it seems the proper way is to specify both the start and stop field even if the same.

But my testing showed that it worked with -k 3 -k 2 just as well as with -k 3,3 -k 2,2

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T12:13:21-07:00
by fmw42
@cgkas. I do not think we can help until you post your original input.png (in PNG format). Posting as JPG changes the colors and so your command to process the image won't work.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T13:46:09-07:00
by cgkas
fmw42 wrote: 2018-10-20T12:13:21-07:00 @cgkas. I do not think we can help until you post your original input.png (in PNG format). Posting as JPG changes the colors and so your command to process the image won't work.
Hello fmw42.

I´m uploading again input.png from dropbox. I hope this time doesn´t affect the quality of image.

Below is the input PNG
Image

And here I show what regions I´d like to get for top boxes and for the other 4 boxes that have white background.

Image

Thanks one more time.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T14:22:20-07:00
by fmw42
That is tough since I see no way to distinguish between the top red box and the one just below it. They are the same color. I think you will have to flood fill just the ones you want to keep or remove. See -fill newcolor -fuzz XX% -draw "color x,y floodfill". Perhaps flood fill all the boxes you want to keep as black and the others as white, since your background is white own the lower right side and between the bottom boxes.

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T15:04:24-07:00
by cgkas
They way I saw was to convert first to black and white and then extract the white boxes and black boxes that are surrounded by white line.

Image

Re: Get coordinates Top, Left, size of some areas

Posted: 2018-10-20T15:31:39-07:00
by fmw42
It does not look much different. Did you try to extract the colored boxes from your input.png?

If that does not work, then you could make a color table image containing only the main colors in your image. The do -remap to ensure that only those colors are in the resulting image. Then do CCL on the color image, and filter on area, then get the list of bounding boxes and colors and filter further in the loop over those on the basis of area of the boxes or width or height and color. Then you can turn those into white boxes on a black background and do CCL again to use my height matching code but only on white boxes to find the pairs.