[GRASS-dev] bilinear in libgis

Glynn Clements glynn at gclements.plus.com
Wed Dec 20 11:44:58 EST 2006


Markus Neteler wrote:

> we also have a bilinear sampling function here:
> 
> lib/gis/sample.c (also bug affected?)
> -> raster_sample_bilinear()

That's the right way round.

> Probably it makes sense to reduce the number of
> functions and maybe move the r.proj functions to
> libgis for wider usage (e.g. r.resamp.interp)?
> Maybe a dumb question... I don't know the internals
> of these modules.

Now that you mention it, lib/gis/sample.c and r.proj[.seg] use the
same equation for cubic interpolation, which isn't the same as
r.resamp.interp.

r.resamp.interp uses:

	c = (u * (u * (u * (c3 - 3*c2 + 3*c1 - c0) + (-c3 + 4*c2  - 5*c1 + 2*c0)) + (c2 - c0)) + 2*c1)/2;

while the others use:

	c = (u * (u * (u * (c3 - c2 + c1 - c0) + (-c3 + c2 - 2*c1 + 2*c0)) + (c2 - c0)) + c1);

Oh; that's because I fixed r.resamp.interp but not the others:

	http://grass.itc.it/pipermail/grassuser/2006-August/035744.html

Running r.slope on the output from "r.proj ... method=cubic" shows the
same kind of banding which occurred with the original r.resamp.interp
algorithm.

OK; I'll do the following:

1. Add a file lib/gis/interp.c containing the following functions:

DCELL G_interp_linear(double u, DCELL c0, DCELL 01)
{
	return  u * (c1 - c0) + c0;
}

DCELL G_interp_bilinear(double u, double v, DCELL c00, DCELL c01, DCELL c10, DCELL c11)
{
	DCELL c0 = G_interp_linear(u, c00, c01);
	DCELL c1 = G_interp_linear(u, c10, c11);

	return     G_interp_linear(v, c0, c1);
}

However, for cubic, r.resamp.interp uses:

DCELL G_interp_cubic(double u, DCELL c0, DCELL c1, DCELL c2, DCELL c3)
{
	return (u * (u * (u * (c3 - 3*c2 + 3*c1 - c0) + (-c3 + 4*c2  - 5*c1 + 2*c0)) + (c2 - c0)) + 2*c1)/2;
}

DCELL G_interp_bicubic(double u, double v,
	DCELL c00, DCELL c01, DCELL c02, DCELL c03,
	DCELL c10, DCELL c11, DCELL c12, DCELL c13,
	DCELL c20, DCELL c21, DCELL c22, DCELL c23,
	DCELL c30, DCELL c31, DCELL c32, DCELL c33)
{
	DCELL c0 = G_interp_cubic(u, c00, c01, c02, c03);
	DCELL c1 = G_interp_cubic(u, c10, c11, c12, c13);
	DCELL c2 = G_interp_cubic(u, c20, c21, c22, c23);
	DCELL c3 = G_interp_cubic(u, c30, c31, c32, c33);

	return     G_interp_cubic(v, c0, c1, c2, c3);
}

2. Change r.proj.seg, r.resamp.interp and lib/gis/sample.c to use
these functions.

3. Change the expression in r.proj to the fixed version. I'll do it
this way rather than using the new lib/gis/interp.c functions to
simplify back-porting. We'll probably end up replacing r.proj with
r.proj.seg soon enough.

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




More information about the grass-dev mailing list