0

I've got a question about bilinear interpolation in the OSRM-Project. I understand the "normal" bilinear interpolation. Here the picture from Wikipedia, what is insane:

Bilinear Interpolation - Wikipedia

Now I'm trying to understand the bilinear interpolation which is used in the OSRM-Project for raster source data.

// Query raster source using bilinear interpolation
RasterDatum RasterSource::GetRasterInterpolate(const int lon, const int lat) const
{
if (lon < xmin || lon > xmax || lat < ymin || lat > ymax)
{
    return {};
}

const auto xthP = (lon - xmin) / xstep;
const auto ythP =
    (ymax - lat) /
    ystep; // the raster texture uses a different coordinate system with y pointing downwards

const std::size_t top = static_cast<std::size_t>(fmax(floor(ythP), 0));
const std::size_t bottom = static_cast<std::size_t>(fmin(ceil(ythP), height - 1));
const std::size_t left = static_cast<std::size_t>(fmax(floor(xthP), 0));
const std::size_t right = static_cast<std::size_t>(fmin(ceil(xthP), width - 1));

// Calculate distances from corners for bilinear interpolation
const float fromLeft = xthP - left; // this is the fraction part of xthP
const float fromTop = ythP - top;   // this is the fraction part of ythP
const float fromRight = 1 - fromLeft;
const float fromBottom = 1 - fromTop;

return {static_cast<std::int32_t>(raster_data(left, top) * (fromRight * fromBottom) +
                                  raster_data(right, top) * (fromLeft * fromBottom) +
                                  raster_data(left, bottom) * (fromRight * fromTop) +
                                  raster_data(right, bottom) * (fromLeft * fromTop))};
}

Original Code here

Can someone explain me how the code works?

The input format are the SRTM data in ASCII format.

The variables height and width are defined as nrows and ncolumns. The variables xstep and ystep are defined as:

return (max - min) / (static_cast<float>(count) - 1)

Where count is height for ystep and width for xstep, max and min similar.

And another question: Can I use the same code for data in TIF-format and the whole world?

Daniel Christoph
  • 309
  • 3
  • 11
  • If as you say, you understand bilinear interpolation already, then surely you should already understand most of this code? – meowgoesthedog Jul 19 '17 at 11:59
  • Okay, maybe I should be clear: I understand the theory behind bilinear interpolation. I understand the basic logic of this code, but I don't understand why e.g. the variable "bottom" is calculated this why, especially the "height - 1". And how does the calculation of the "fromX" variables work. – Daniel Christoph Jul 19 '17 at 12:06

1 Answers1

2

Horizontal pixel coordinates are in the range [0, width - 1]; similarly vertical coordinates are in [0, height - 1]. (Zero-indexing convention used in many many languages including C++)

The lines

const auto xthP = (lon - xmin) / xstep; (and for ythP)

Convert the input image-space coordinates (long, lat) into pixel coordinates. xstep is the width of each pixel in image-space.

Rounding this down (using floor) gives pixels intersected by the sample area on one side, and rounding up (ceil) gives the pixels on the other side. For the X-coordinate these give left and right.

The reason for using fmin and fmax are to clamp the coordinates so that they don't exceed the pixel coordinate range.


EDIT: since you are trying to interpret this picture, I'll list the corresponding parts below:

  • Q11 = (left, top)
  • Q12 - (left, bottom), etc.
  • P = (xthP, ythP)
  • R1 = fromTop, R2 = fromBottom etc.

A good start point would be http://www.cs.uu.nl/docs/vakken/gr/2011/Slides/06-texturing.pdf, slide 27. In future though, Google is your friend.

meowgoesthedog
  • 14,670
  • 4
  • 27
  • 40
  • Okay! But what is with "fromRight = 1 - fromLeft;" and "fromBottom = 1 - fromTop;"? Why the "1 - x" ? – Daniel Christoph Jul 19 '17 at 12:18
  • @DanielChristoph then you clearly haven't understood bilinear interpolation in the context of implementation. These calculate the *fractional* intersection with pixels on either side of the sampling box, and are then used together to calculate the fractional areas of the sampling box occupied by each pixel it overlaps. These areas are then used as the weights for interpolation; so essentially you only understand the last line of the code. – meowgoesthedog Jul 19 '17 at 12:20
  • @DanielChristoph btw that picture from Wikipedia does not really help your situation, since the labelling is very different. I advise you to ignore it in the context of this code. – meowgoesthedog Jul 19 '17 at 12:27
  • Okay, maybe this is my problem. I'm trying to "translate" the code from OSRM to this picture. – Daniel Christoph Jul 19 '17 at 12:31
  • do you have a nice resource, where I can learn the bilinear interpolation in the context of implementation? – Daniel Christoph Jul 19 '17 at 12:36
  • @DanielChristoph updated answer with some more explanations – meowgoesthedog Jul 19 '17 at 12:42