[GRASS-user] circular neighborhoods?

Glynn Clements glynn at gclements.plus.com
Thu Feb 21 22:21:45 EST 2008


Tom Russo wrote:

> When the "-c" option to r.neighbors is selected, a neighborhood mask of booleans
> is created by this loop (in pseudocode):
> 
>   neighborhoodDistance=neighborhoodSize/2 (in integer math)
>   for (i=0; i<neigborhoodSize; i++)
>     for (j=0; j<neighborhoodSize; j++)
>        mask[i][k]= ( (i-neighborhoodDistance)^2 + (j-neighborhoodDistance)^2 <= (neighborhoodDistance)^2
> 
> So in a 3x3 example, neighborhoodSize=3, neighborhoodDistance=1, and your
> first diagram has "o"s where the mask is true.  The corners of the square
> wouldn't be in the mask (as in Eric's 3x3), because those points would have 
> the left hand side of the inequality equal to 2, making the mask false.
> 
> I haven't actually *tried* the code, but that is what the block of code in
> gather.c for circular neighborhoods says it should be doing.

FWIW, here are the exact masks for the first few sizes:

3x3	. X . 
	X X X 
	. X . 

5x5	. . X . . 
	. X X X . 
	X X X X X 
	. X X X . 
	. . X . . 

7x7	. . . X . . . 
	. X X X X X . 
	. X X X X X . 
	X X X X X X X 
	. X X X X X . 
	. X X X X X . 
	. . . X . . . 

9x9	. . . . X . . . . 
	. . X X X X X . . 
	. X X X X X X X . 
	. X X X X X X X . 
	X X X X X X X X X 
	. X X X X X X X . 
	. X X X X X X X . 
	. . X X X X X . . 
	. . . . X . . . . 

11x11	. . . . . X . . . . . 
	. . X X X X X X X . . 
	. X X X X X X X X X . 
	. X X X X X X X X X . 
	. X X X X X X X X X . 
	X X X X X X X X X X X 
	. X X X X X X X X X . 
	. X X X X X X X X X . 
	. X X X X X X X X X . 
	. . X X X X X X X . . 
	. . . . . X . . . . . 

13x13	. . . . . . X . . . . . . 
	. . . X X X X X X X . . . 
	. . X X X X X X X X X . . 
	. X X X X X X X X X X X . 
	. X X X X X X X X X X X . 
	. X X X X X X X X X X X . 
	X X X X X X X X X X X X X 
	. X X X X X X X X X X X . 
	. X X X X X X X X X X X . 
	. X X X X X X X X X X X . 
	. . X X X X X X X X X . . 
	. . . X X X X X X X . . . 
	. . . . . . X . . . . . . 

The "pips" on the four edges arise from the fact that the distance
from the centres of those cells to the centre of the centre cell is
exactly equal to the radius. If the radius wasn't truncated to an
integer (e.g. 5x5 => radius = 2.5 instead of 2), the masks would look
slightly more circular.

If you want some other shape, you can achieve the desired result by
using the weight= option to specify a weights file where all values
are equal (for method=sum, the sum of the weights should be 1).

Actually, the values don't have to be equal. You might want to make
the weights at the edge of the neighbourhood vary according to the
proportion of the cell that lies inside the circle, effectively
anti-aliasing the mask.

For aggregates where a weighted calculation isn't meaningful
(specifically: minimum, maximum, diversity and interspersion), the
weights are used to create a binary mask, where zero causes the cell
to be ignored and any non-zero value causes the cell to be used.

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


More information about the grass-user mailing list