[GRASS-user] speeding up context evaluation...

Hi list,

for a validation exercise I need to extract the class values around certain pixel location.

I have a map with all the locations (numbered) and a map with the validation map.

The code you find below is the one I came up with to get this information (only output to terminal for the moment).

However, this code includes a loop and is terribly slow. Has anyone an idea how to speed things up?

Kind regards,
Koen

---------- my code -------------

#!/bin/bash

###########################################################################################################################

Get context around pixels…

!!! Bash script only works within the GRASS terminal !!!

###########################################################################################################################

get number of pixels in location file… write to variable $pixels…

pixels=r.info -r map=$1 | tail -n +2 | sed 's/max=//'

echo “their are $pixels groundtruth points…”

for i in seq 1 $pixels;
do

echo “evaluating pixel $i of $pixels pixels…”

Make MASK based upon pixel number evaluate one at a time. Mask name is MASK and patch.mask

after renaming… If kept as MASK it will apply to all operations and is a system wide setting (not wanted)…

r.mask -o input=$1 maskcats=$i --quiet
g.rename rast=MASK,pixel.mask --overwrite --quiet

create buffer around pixel value…

r.buffer input=pixel.mask output=tmp.buffer distances=4 units=meters --overwrite --quiet

writes temporary reclass rules file…

echo “1 = NULL” > tmp.rules
echo “2 = 1” >> tmp.rules
echo “end” >> tmp.rules

reclass context values using rules above…

r.reclass input=tmp.buffer output=context.mask rules=tmp.rules --overwrite

calculate category statistics for pixel and context location…

r.mapcalculator amap=pixel.mask bmap=$2 formula=AB outfile=pixel.category help=- --overwrite --quiet
echo “pixel data…”
r.stats -c -n input=pixel.category fs=space nv=
nsteps=255

r.mapcalculator amap=context.mask bmap=$2 formula=AB outfile=context.category help=- --overwrite --quiet
echo “context data…”
r.stats -c -n input=context.category fs=space nv=
nsteps=255

done

clean up tmp files…

rm tmp.rules
g.remove rast=pixel.mask
g.remove rast=context.mask

echo “!!!DONE!!!”
echo “#########################################################################”

Sorry, I was not reading carefully Your code snippet, but can't You
just use mapcalc's ability to access neighborhood pixel values (see
"THE NEIGHBORHOOD MODIFIER" in help page). Like
output=if(location[-1,-1],validation,null()) || etc...
It may eliminate need to create buffer, mask etc. still if it takes
lot of time, consider to create new C module. Also take a look at
v.sample.

Maris.

2008/12/2, Hufkens Koen <koen.hufkens@ua.ac.be>:

Hi list,

for a validation exercise I need to extract the class values around certain
pixel location.

I have a map with all the locations (numbered) and a map with the validation
map.

The code you find below is the one I came up with to get this information
(only output to terminal for the moment).

However, this code includes a loop and is terribly slow. Has anyone an idea
how to speed things up?

Kind regards,
Koen

---------- my code -------------

#!/bin/bash
#
###########################################################################################################################
#
# Get context around pixels...
#
# !!! Bash script only works within the GRASS terminal !!!
#
###########################################################################################################################

#
# get number of pixels in location file... write to variable $pixels...
#

pixels=`r.info -r map=$1 | tail -n +2 | sed 's/max=//'`

echo "their are $pixels groundtruth points..."

for i in `seq 1 $pixels`;
do

echo "evaluating pixel $i of $pixels pixels..."

#
# Make MASK based upon pixel number evaluate one at a time. Mask name is
MASK and patch.mask
# after renaming... If kept as MASK it will apply to all operations and is a
system wide setting (not wanted)...
#

r.mask -o input=$1 maskcats=$i --quiet
g.rename rast=MASK,pixel.mask --overwrite --quiet

#
# create buffer around pixel value...
#

r.buffer input=pixel.mask output=tmp.buffer distances=4 units=meters
--overwrite --quiet

#
# writes temporary reclass rules file...
#

echo "1 = NULL" > tmp.rules
echo "2 = 1" >> tmp.rules
echo "end" >> tmp.rules

#
# reclass context values using rules above...
#

r.reclass input=tmp.buffer output=context.mask rules=tmp.rules --overwrite

#
# calculate category statistics for pixel and context location...
#

r.mapcalculator amap=pixel.mask bmap=$2 formula=A*B outfile=pixel.category
help=- --overwrite --quiet
echo "pixel data..."
r.stats -c -n input=pixel.category fs=space nv=* nsteps=255

r.mapcalculator amap=context.mask bmap=$2 formula=A*B
outfile=context.category help=- --overwrite --quiet
echo "context data..."
r.stats -c -n input=context.category fs=space nv=* nsteps=255

done

#
# clean up tmp files...
#

rm tmp.rules
g.remove rast=pixel.mask
g.remove rast=context.mask

echo "!!!DONE!!!"
echo
"#########################################################################"

Hufkens Koen wrote:

for a validation exercise I need to extract the class values around certain pixel location.

I have a map with all the locations (numbered) and a map with the validation map.

The code you find below is the one I came up with to get this information (only output to terminal for the moment).

However, this code includes a loop and is terribly slow. Has anyone an idea how to speed things up?

If your groundtruth points are sufficiently spaced that their buffers
don't overlap[1], you can avoid the loop by creating a single buffer
map rather than one for each category.

[1] Or you can accept assigning overlapped cells to the nearest point.

--
Glynn Clements <glynn@gclements.plus.com>