Explanation of Bicubic interpolation in Matlab?

7.6k views Asked by At

I am confused by Matlab's example on Bicubic interpolation at http://www.mathworks.com/help/vision/ug/interpolation-methods.html#f13689

I think I understand their Bilinear example. It seems like they took the averages of the adjacent translated values on either side. So, to get the 0.5 in their first row, first column, the average of 0 and 1 was taken.

For their Bicubic interpolation example, I am rather confused by their method. They say that they take the "weighted average of the two translated values on either side".

In their example, they have

1 2 3
4 5 6
7 8 9

and in their first step of Bicubic interpolation, they add zeros to the matrix and translate it by 0.5 pixel to the right to get the following:

0 0 0 1 1 2 2 3 3 0 0 0 0
0 0 0 4 4 5 5 6 6 0 0 0 0
0 0 0 7 7 8 8 9 9 0 0 0 0

Then, using weighted average, they get

0.375 1.500 3.000 1.625
1.875 4.875 6.375 3.125
3.375 8.250 9.750 4.625

However, I am not sure how they got those numbers. Instead of 0.375 in the first row, first column, I would have done instead (1 * 3/8 + 2 * 1/8) = 5/8 . This is because the format seems to be

0  _  0  1  1  _  2
3d    d     d     3d

where d is the distance.

So to take the weighted average of the translated values, we can note that the we can first do (3d + d + d + 3d) = 1 and so d = 1/8. That means we should put 3/8 weight on each of the closer translated values and 1/8 weight on each of the further translated values. That leads to (0 * 1/8 + 0 * 3/8 + 1 * 3/8 + 2 * 1/8), which is 5/8 and does not match their 3/8 result. I was wondering where I went wrong.

Thanks!

3

There are 3 answers

0
Peter de Rivaz On BEST ANSWER

Bicubic interpolation uses negative weights (this sometimes results in overshoot when filtering).

In this example, the weights used are:

-1/8 5/8 5/8 -1/8

These weights sum to 1, but give larger weight to the middle samples and smaller (negative) weights to the outer samples.

Using these weights we get the observed values, e.g.

0.375 = 5/8*1 -1/8*2
1.5 = 5/8*1+5/8*2 -1/8*3
2
nhnminh On

I found this topic imresize - trying to understand the bicubic interpolation could solve your confusion, especially for the comment with 7 upvotes. By the way, in that comment, the author states that alpha = -0.5 in Matlab, it's contrast to my experience. I wrote 2 functions to test, and I figured out Matlab set alpha = -0.9.

Here are the code I could provide:

Cubic:

function f = cubic(x)
    a = -0.9;
    absx = abs(x);
    absx2 = absx.^2;
    absx3 = absx.^3;
    f = ((a+2)*absx3 - (a+3)*absx2 + 1) .* (absx <= 1) + ...
        (a*absx3 -5*a*absx2 + 8*a*absx - 4*a) .* ((1 < absx) & (absx <= 2));
end

Interpolation with Bi-cubic:

function f = intpolcub(x1,x2,x3,x4,d)
    f = x1*cubic(-d-1) + x2*cubic(-d) + x3*cubic(-d+1) + x4*cubic(-d+2);
end

You could test with the following line of code:

intpolcub(0,0,1,2,0.5)

This reproduce the first number in the output matrix of Matlab example about bicubic interpolation you have mentioned above.

0
James On

Matlab (R2017a) works with a=-1 so:

For cubic:

function f_c = cubic(x)
    a = -1;
    absx = abs(x);
    absx2 = absx.^2;
    absx3 = absx.^3;
    f_c = ((a+2)*absx3 - (a+3)*absx2 + 1) .* (absx <= 1) + ...
        (a*absx3 -5*a*absx2 + 8*a*absx - 4*a) .* ((1 < absx) & (absx <= 2));
end

And for Bicubic interpolation:

function f_bc = intpolcub(x1,x2,x3,x4,d)
    f_bc = x1*cubic(-d-1) + x2*cubic(-d) + x3*cubic(-d+1) + x4*cubic(-d+2);
end

Test:

intpolcub(0,0,1,2,0.5)

Explicitly it goes:

f_bc = 0*cubic(-0.5-1)+0*cubic(-0.5)+1*cubic(-0.5+1)+2*cubic(-0.5+2) = 1*cubic(0.5)+2*(cubic(1.5);

Now the calculation of cubic for 0.5 (f_c<1) and 1.5 (1<f_c<=2) is:

cubic(0.5) = (-1+2)*0.5^3-(-1+3)*0.5^2+1 = 5/8

cubic(1.5) = (-1)*1.5^3-5*(-1)*1.5^2+8*(-1)*1.5-4*(-1) = -1/8

So that f_bc is:

f_bc = 5/8+2*(-1/8) = 0.375