bilinear interpolation

Assume the source image size is MXN and the target image is AXB. Then the Benchambi of the two images were: m/a and n/b. Note that this ratio is usually not an integer, and that the programming store uses floating-point types. The first (I,J) pixel of the target image (i row j column) can be returned to the source image by the edge length ratio. Its corresponding coordinates are (i*m/a,j*n/b). Obviously, this corresponding coordinate is generally not an integer, and the coordinates of a non integer cannot be used on discrete data such as images. bilinear interpolation computes the value of the point (grayscale or RGB) by looking for the nearest four pixels from this corresponding coordinate. If your corresponding coordinates are (2.5,4.5), then the nearest four pixels are (2,4), (2,5), (3,4), (3,5).

If the image is a grayscale image, then the mathematical model of the gray value of the (I,J) point is:

F (x,y) =b1+b2x+b3y+b4xy

Among them, the b1,b2,b3,b4 is the correlation coefficient.

Or:

F (i,j) =w1*p1+w2*p2+w3*p3+w4*p4;

where PI (i=1,2,3,4) is the nearest four pixel, WI (i=1,2,3,4) is the corresponding weight of each point. For the calculation of weights, see Wikipedia below.

The calculation process is as follows:

As shown in the figure, the q12,q22,q11,q21 is known, but the point to be interpolated is p. This is going to use bilinear interpolation, first in the x-axis direction, the R1 and R2 two points interpolation, this is very simple, and then according to R1 and R2 to the P point interpolation, which is called bilinear interpolation.

Appendix: Wikipedia--bilinear interpolation:

Bilinear interpolation, also known as double linear interpolation. In mathematics, bilinear interpolation is a linear interpolation extension of two variable interpolation functions, and its core idea is to make a linear interpolation in two directions respectively.

If we want the value of the unknown function at the point, suppose we know the value of the function at,,, and four points.

First in the x direction linear interpolation, get

And then linear interpolation in the Y direction to get

So you get the results you want,

If you select a coordinate system to make four known point coordinates (0, 0), (0, 1), (1, 0), and (1, 1), then the interpolation formula can be reduced to

Or it is represented by a matrix operation

The result of this interpolation method is usually not linear, and the result of linear interpolation is independent of the order of interpolation. First the Y-direction interpolation, and then the X-directional interpolation, the result is the same. bilinear interpolation in OpenCV and matlab

The premise of this part is that you already know what bilinear interpolation is and, given the source and target image dimensions, you can calculate the value of a pixel in the target image with the pen. Of course, the best thing is that you have implemented a large number of online blogs on the internet a number of original or reprinted bilinear interpolation algorithm, and then found that the calculated results and MATLAB, OPENCV corresponding to the resize () function of the results are completely different.

What the hell is going on here?

In fact, the answer is very simple, is the choice of coordinate system, or the source image and target image of the corresponding problem.

According to some blogs on the internet, source image and target image of the origin (0,0) are selected in the upper left corner, and then based on the interpolation formula to calculate the target image per pixel, assuming you need to reduce a 5x5 image to 3x3, then the source image and the target image of the corresponding relationship between each pixel is as follows:

Only a line was drawn, used as a gesture, it is obvious from the diagram that if you choose the upper-right corner as the origin (0,0), then the rightmost and bottom pixels are not actually involved in the calculation, and the gray values computed by each pixel point of the target image are also relative to the source image on the left side.

So, what about the coordinates plus 1 or the bottom right corner for the original point? Unfortunately, the same effect, but this time the image will be on the lower right.

The best method is that two images of the geometric center overlap, and the target image of each pixel is equal spacing, and both sides have a certain margin, which is also the MATLAB and OpenCV practice. The following figure:

If you do not understand what I said above, it doesn't matter, as long as the corresponding coordinates in the calculation of the following formula can be,

int x= (i+0.5) *m/a-0.5

int y= (j+0.5) *n/b-0.5

Replace the following formula:

int x=i*m/a

int y=j*n/b

The correct bilinear interpolation result is obtained by using the above formula.

Summarize:

To sum up, I have learned so few lessons.

1. Some of the information on the Internet sometimes is not reliable, they still have to do more experiments.

2. Do not underestimate some simple, basic algorithm, so that you write you may not be able to write, and there may be some mysterious hidden.

3. More hands-on programming, more experience algorithm, see Daniel write the source code (although sometimes very difficult, but to stick to see).

In image processing, bilinear interpolation algorithm is used very high frequency, such as in the image scaling, in all distortion algorithm, can use this algorithm to improve the processing of visual effects. First, let's look at the introduction to the algorithm.

In mathematics, bilinear interpolation algorithm can be regarded as the extension of linear interpolation between two variables. The key idea for this process is to perform linear interpolation in one direction and then interpolation in the other direction. The figure below shows the approximate meaning of the process.

A simple mathematical expression can be expressed as follows:

F (x,y) =f (0,0) (1-x) (1-y) +f (1,0) x (1-y) +f (0,1) (1-x) y+f, (1,1) XY

To merge related items, write as: f (x,y) = (f (0,0) (1-x) +f (1,0) x) (1-y) + (f (0,1) (1-x) +f (1,1) x) y

From the above, we can see that this process has a large number of floating-point operations, for the image of such a large computational user, is a time-consuming process.

Considering the specificity of the image, his pixel value of the calculation results need to fall between 0 to 255, up to only 256 results, from the above formula can be seen, in general, the calculated F (x,y) is a floating-point number, we also need to take the floating-point number to rounding. Therefore, we can consider all the similar 1-x, 1-y variables in the process to enlarge the appropriate multiples, get the corresponding integer, and finally divided by a suitable integer as the result of interpolation.

How to take this appropriate magnification, from three aspects to consider, first: precision, if this number has been too small, then after calculation may result in large errors. Second, the number cannot be too large, and the assembly causes the computational process to exceed the range that can be expressed by long shaping. Third: Speed consideration. If the magnification is 12, then the formula in the final result should be divided by 12*12=144, but if you take 16, then the last divisor is 16*16=256, the number is good, we can move to the right to achieve, and the right to move more than the average division faster.

Considering the above three, we choose the number 2048 is more appropriate.

Here we assume that an algorithm gets the coordinates we're going to sample, respectively Posx and Posy, where posx=25.489,posy=58.698. The similar code fragment for this procedure is as follows: 1 newx = Int (posx) ' Rounding down, newx=25

2 Newy = Int (posy) ' Rounding down, newy=58

3 Partx = (posx-newx) * 2048 ' corresponding to X in expression

4 party = (posy-newy) * 2048 ' corresponding y in the expression

5 INVX = 2048-partx ' corresponds to the 1-x in an expression

6 Invy = 2048-party ' corresponds to the 1-y in an expression

7

8 Index1 = samstride * newy + newx * 3 ' calculates the memory address of the pixel near the upper-left corner of the sampling point

9 Index2 = Index1 + samstride ' left lower corner pixel address

10 imagedata (speed + 2) = ((Sample (index1 + 2) * invx + sample (index1 + 5) * partx) * InvY + (index2 + 2) * InvX + Sample (index2 + 5) * &NBSP;PARTX) * party) \ 4194304 ' handles red component 11 ImageData (speed + 1) = ((Sample (index1 + 1) * invx + sample ( index1 + 4 * partx) * InvY + (Sample (index2 + 1) * invx + sample (index2 + 4) * PARTX) *  Party) \ 4194304 ' handling of green components

ImageData (Speed) = (sample (INDEX1) * INVX + sample (INDEX1 + 3) * partx) * Invy + (sample (INDEX2) * INVX + Sample (INDEX2 + 3) * partx) * Party) \ 4194304 ' Processing blue component

The variables involved in the above code are integers (POSX and posy, of course, are floating-point types).

The sample array in code holds the image data sampled from it, samstride the scanned row size for the image.

Observe the code above, except that there are 2 of them involving floating-point computations, and the rest are the operations between integers.

In the basic language, if all of the advanced optimizations are checked at compile time, then \ 4194304 will be compiled to >>22, that is, 22 digits to the right, if the C language is used, write directly as >>22.

It should be noted that before this generation code is made, it is necessary to ensure that posx and posy are within reasonable bounds, that is, the width and height range of the sampled image cannot be exceeded.

Through this improvement, the speed is faster than the direct use of floating-point type at least 100%, and the effect of the treatment after the basic no difference. Using MATLAB to achieve bilinear interpolation (image amplification/reduction)

Reference: http://www.cnblogs.com/tiandsp/archive/2012/12/03/2800201.html

Close all;

Clear all;
CLC m=1.8; % Zoom or shrink height n=2.3;
% Enlarge or shrink width img=imread (' lena.jpg ');
Imshow (IMG);
[H W]=size (IMG);
Imgn=zeros (H*m,w*n); Rot=[m 0 0;0 N 0;0 0 1];
% transformation matrix for I=1:h*m for J=1:w*n Pix=[i J 1]/rot;
Float_y=pix (1)-floor (PIX (1));
Float_x=pix (2)-floor (PIX (2));
The If PIX (1) < 1 boundary processing pix (1) = 1;
End If PIX (1) > H pix (1) = h;
End If PIX (2) < 1 pix (2) = 1;
End If PIX (2) > W pix (2) =w; End Pix_up_left=[floor (PIX (1)) Floor (PIX (2))];
% four adjacent dots pix_up_right=[floor (pix (1)) ceil (PIX (2))];
Pix_down_left=[ceil (PIX (1)) Floor (PIX (2))];
Pix_down_right=[ceil (PIX (1)) ceil (PIX (2))]; value_up_left= (1-float_x) * (1-float_y);
% calculates the weighted value_up_right=float_x* (1-float_y) near four points; value_down_left= (1-float_x) *float_y;
value_down_right=float_x*float_y; % by weight double linear interpolation imgn (i,j) =value_up_left*img (Pix_up_left (1), Pix_up_left (2)) + ... value_up_right*img (p
Ix_up_right (1), Pix_up_right (2)) + ... value_down_left*img (pix_down_left (1), Pix_down_left (2)) + ...
Value_down_right*img (Pix_down_right (1), Pix_down_right (2)); End-End Figure,imshow (uint8 (IMGN))

When the original image is enlarged