Blog

Bilinear interpolation explained

Your table has values across the top and down the side, and you need a point between both. Worked two ways, with the arithmetic shown.


Your table has one variable running across the top and another running down the side. The value you need falls between two columns and between two rows at the same time, so a single interpolation will not get you there.

Bilinear interpolation is the fix. You interpolate twice, once along each direction. Engineers usually call it double interpolation.

The quick answer

Interpolate along the top edge of your rectangle, then along the bottom edge. That gives you two numbers on the same vertical line. Interpolate between those two and you are done.

The order does not matter. Doing rows first or columns first gives the same answer, which is a free way to check your work.

The setup

You know the value at four corners of a rectangle and want a point inside it. Use these numbers, from a made up efficiency table with load across the top and temperature down the side:

 x = 10x = 20
y = 0100120
y = 10140180

Target: the value at x = 15, y = 5, which is the exact centre of the rectangle.

Round one: work across, then down

x = 15 is halfway between 10 and 20, so the fraction across is 0.5.

Take the top row, where y = 0. It runs from 100 to 120:

100 + 0.5 × (120 − 100) = 100 + 10 = 110

Take the bottom row, where y = 10. It runs from 140 to 180:

140 + 0.5 × (180 − 140) = 140 + 20 = 160

You now have two values, 110 and 160, both sitting at x = 15. They are on the same vertical line, one at y = 0 and one at y = 10. Interpolate between them. y = 5 is halfway, so the fraction is 0.5 again:

110 + 0.5 × (160 − 110) = 110 + 25 = 135

Round two: the other order

Do the columns first instead. The left column, at x = 10, runs from 100 to 140:

100 + 0.5 × (140 − 100) = 120

The right column, at x = 20, runs from 120 to 180:

120 + 0.5 × (180 − 120) = 150

Now interpolate between 120 and 150 across x:

120 + 0.5 × (150 − 120) = 135

Same 135. Getting a different number the second time means you made an arithmetic slip somewhere, and this check costs you about twenty seconds.

Doing it in one go

Expanding both rounds into a single expression gives each corner its own weight:

value = (1−tx)(1−ty)f11 + tx(1−ty)f21 + (1−tx)tyf12 + txtyf22

Each corner is weighted by the area of the little rectangle diagonally opposite it. Stand near one corner and the box opposite you is large, so that corner counts for most of your answer. The four weights always add to 1, which means the result can never come out above or below all four corner values.

At the exact centre all four weights are 0.25, so the answer is just the average of the corners:

0.25 × (100 + 120 + 140 + 180) = 0.25 × 540 = 135

The surface is not flat

"Bilinear" means straight in each direction taken by itself, not straight overall. Multiply the four-weight version out and you get a term with x and y multiplied together:

value = a + bx + cy + d·xy

That last term bends the surface into a saddle shape. Walk in a straight line parallel to either axis and the values change at a steady rate. Walk diagonally across the cell and they curve.

You can see it in the numbers above. Along the top row the value rises by 20 across the cell. Along the bottom row it rises by 40. How fast x matters depends on where you are in y, and a flat plane cannot do that. Had the corners been 100, 120, 140 and 160, the rise would have been 20 on both rows, the xy term would disappear, and the surface really would be flat.

Where you run into this

Engineering property tables. Superheated steam, refrigerant properties, compressibility charts and engine maps are all indexed by two variables. There is a full worked example on real thermodynamic data in interpolating steam tables.

Resizing images. Scaling a photo up maps each new pixel to a position between four original pixels, and bilinear blending decides its colour. It is the default in most image software because it is cheap and avoids the blocky staircase edges you get from just picking the nearest pixel. The trade-off is slight softening, since averaging four pixels blurs fine detail. Bicubic uses sixteen neighbours, keeps edges crisper, and costs about four times as much.

Maps and elevation data. Terrain height is stored on a grid. Getting the height at a specific latitude and longitude means bilinear sampling of the four grid points around you. Same for weather model output and satellite temperature grids.

Graphics hardware. Your GPU does bilinear filtering in dedicated circuitry, on every textured pixel, millions of times a second. It is very likely the most executed interpolation in computing.

Limits worth knowing

The value is continuous as you cross from one cell to the next, but the slope is not. Render a 3D surface this way and you will see faint creases running along the grid lines where the slope jumps.

It also only works on a regular grid. Scattered points need something else, such as building triangles between them, inverse distance weighting, or kriging.

Error grows with cell size the same way it does in one dimension, and now it happens in both directions at once. A coarse grid over a strongly curved surface is where results start to visibly disagree with reality.

Finally, do not do this to categories. Averaging land-cover codes or class labels produces a number that means nothing at all. Anything that is a label rather than a measurement needs nearest-neighbour instead.

Each of the two steps is ordinary linear interpolation, so you can check either one in the calculator before combining them.

Try it yourself

Run these numbers through the calculator and check the working step by step.

Open the calculator