Get coordinates Top, Left, size of some areas
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Get coordinates Top, Left, size of some areas
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
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
It seems to be the order. I get a different list order.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:
It should list this in the following 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
I explained the logic above. If you have specific questions, then ask away.Code: Select all
264x40+680+109 423x145+530+203 423x145+70+203 422x205+70+379 423x205+530+379 422x355+70+589 423x355+530+589
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
Thanks a lot fmw42 for your help, time, patience.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Get coordinates Top, Left, size of some areas
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.
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.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Get coordinates Top, Left, size of some areas
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
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
Hi fmw42.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
Thanks for continue helping me.
I was able to fix the sort issue changing from
Code: Select all
sort -n -t "+" -k 3,2
Code: Select all
sort -t "+" -k3n -k2n
Below an image of what I'm saying.
Thanks again for the kind help.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Get coordinates Top, Left, size of some areas
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:
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:
... and the result is as Fred showed.
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:
I suppose that having a start position that is after the stop position isn't valid.-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.
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`)
snibgo's IM pages: im.snibgo.com
Re: Get coordinates Top, Left, size of some areas
For me it works when I put sort in this way as mentioned in previous post.
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.
Code: Select all
sort -t "+" -k3n -k2n
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.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Get coordinates Top, Left, size of some areas
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.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Get coordinates Top, Left, size of some areas
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:
... and this works fine.
Code: Select all
null: | awk 'NR>2 {print $2}' | sort -g -t "+" -k 3 -k 2`)
snibgo's IM pages: im.snibgo.com
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Get coordinates Top, Left, size of some areas
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
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
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Get coordinates Top, Left, size of some areas
@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
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
And here I show what regions I´d like to get for top boxes and for the other 4 boxes that have white background.
Thanks one more time.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Get coordinates Top, Left, size of some areas
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
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.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Get coordinates Top, Left, size of some areas
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.
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.