Search code examples
c++arraysbmpbilinear-interpolation

The Concept of Bilinear Interpolation by Accessing 2-d array like 1-d array does


In 2-d array, there are pixels of bmp files. and its size is width(3*65536) * height(3*65536) of which I scaled. It's like this.

1   2   3   4 

5   6   7   8

9  10  11  12

Between 1 and 2, There are 2 holes as I enlarged the original 2-d array. ( multiply 3 )

I use 1-d array-like access method like this.

array[y* width + x]

index
0 1 2 3 4 5 6 7 8 9...   
1     2     3     4    5    6    7    8    9    10    11    12
(this array is actually 2-d array and is scaled by multiplying 3)

now I can patch the hole like this solution. In double for loop, in the condition (j%3==1)

Image[i*width+j] = Image[i*width+(j-1)]*(1-1/3) + Image[i*width+(j+2)]*(1-2/3)

In another condition ( j%3==2 )

Image[i*width+j] = Image[i*width+(j-2)]*(1-2/3) + Image[i*width+(j+1)]*(1-1/3)

This is the way I know I could patch the holes which is so called "Bilinear Interpolation".

I want to be sure about what I know before implementing this logic into my code. Thanks for reading.


Solution

  • Bi linear interpolation requires either 2 linear interpolation passes (horizontal and vertical) per interpolated pixel (well, some of them only require 1), or requires up to 4 source pixels per interpolated pixel.

    Between 1 and 2 there are two holes. Between 1 and 5 there are 2 holes. Between 1 and 6 there are 4 holes. Your code, as written, could only patch holes between 1 and 2, not the other holes correctly.

    In addition your division is integer division, and does not do what you want.

    Generally you are far better off writing a r=interpolate_between(a,b,x,y) function, that interpolates between a and b at step x out of y. Then test and fix. Now scale your image horizontally using it, and check visually you got it right (especially the edges!)

    Now try using it to scale vertically only.

    Now do both horizontal, then vertical.

    Next, write the bilinear version, which you can test again using the linear version three times (will be within rounding error). Then try to bilinear scale the image, checking visually.

    Compare with the two-linear scale. It should differ only by rounding error.

    At each of these stages you'll have a single "new" operation that can go wrong, with the previous code already validated.

    Writing everything at once will lead to complex bug-ridden code.