[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告

Introduction:

Through this LAB, I have known the principle and formula of nearest neighbor interpolation and bilinear interpolation, and Use nearest neighbor interpolation and bilinear interpolation to interpolate a grey scale image. At the same time, I find some aspects that can be optimized in these two methods.

Lab results & Analysis:

  1. Use nearest neighbor interpolation to interpolate a grey scale image:
  1. Introduction of the nearest neighbor interpolation algorithm:

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第1张图片

Figure 1 the area of pixels

 

Let i + u, j + v (i, j is a positive integer, u, v is a decimal greater than zero and less than 1) be the pixel coordinate we want to get, then the greyscale we want to know is f (i + u, j + v).

If (i + u, j + v) falls in area A, that is u<0.5 and v<0.5, the greyscale of the upper-left pixel will be assigned to the pixel we want to get. Similarly, if it falls in area B, the greyscale of the upper-right pixel will be assigned; if it falls in area C, the greyscale of the lower-left pixel will be assigned; if it falls in area D, the greyscale of the lower-right pixel will be assigned.

This algorithm is simple and easy to understand and program, so that I will not write the pseudo code for this algorithm. I will give detailed comments in the program.

 

  1. Matlab codes:
clear;

close all;

clc;

img = imread('rice.tif');

[ input_img,new_img ] = Nearest_11711118(img,[.8,.8]);

show(img,new_img);



function show(img,new_img)%print the figure

[height,width] = size(img);

figure;imshow(img);

axis on

title(['Input Figure with Size(',num2str(height),'*',num2str(width),'):']);

[new_height,new_width,] =size(new_img);

figure;imshow(new_img);

axis on

title(['Output Figure with Size( ',num2str(new_height),'*',num2str(new_width),'):']);

end



function[ input_img,new_img ]= Nearest_11711118(input_img, dim)





input_img=double(input_img);

swh=size(input_img); %Get the width and height of the original image



inputWidth=swh(:,2); %Get the width  of the original image

inputHigh=swh(:,1); %Get the  height of the original image

r=dim(:,1);

c=dim(:,2);

outputHigh=ceil(inputHigh * c);

outputWidth=ceil(inputWidth * r);

new_img=zeros(outputHigh,outputWidth);

orignalx = [1:outputHigh];

orignaly = [1:outputWidth];

for i=1:outputHigh

    orignalx(i)=round(i/r);

end

for j=1:outputWidth

    orignaly(j)=round(j/c);

end

for i=1:outputHigh

    for j=1:outputWidth

      

        if(orignalx(i) < 1) %If the coordinates cross the border, make adjustments

                        orignalx(i) = 1;

        end

        if(orignalx(i) > inputHigh)

            orignalx(i) = swh;

        end

        if(orignaly(j) < 1)

            orignaly(j) = 1;

        end

        if(orignaly(j) > inputWidth)

            orignaly(j) = inputWidth;

        end

        new_img(i,j)=input_img(orignalx(i),orignaly(j)); %The Grayscale of the position of the scaled image coordinate at the original image is assigned to the scaled image

    end

end

new_img=uint8(new_img);



end

 

 

  1. The output figure of the program:

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第2张图片

Figure 2 shrinked figure

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第3张图片

Figure 3 enlarged figure

 

  1. Analysis and conclusions:

The Advantages and disadvantages of nearest neighbor interpolation:

  1. Advantages: The algorithm is simple, the program computation is small, the speed is fast.
  2. Disadvantages: Nearest neighbor interpolation will cause the discontinuity of the greyscale of the image generated by interpolation, and there may be obvious zigzag where the greyscale changes. So that using nearest neighbor interpolation to enlarge image is very jagged and shrink image is very distorted.

Then we take a closer look at our pictures to verify the Analysis:  

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第4张图片

Figure 4 closer look of shrink figure

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第5张图片

Figure 5 : the closer look of the enlarged figure

 

     We can see it clearly the details in enlarge image is very jagged and details in shrink image is very distorted. The root of the result is bad is the nearest neighbor interpolation caused serious image distortion, for example, when the target figure's push to get the coordinates of the source map is the coordinates of a floating number, the rounding method was adopted, directly using the floating-point number and the nearest pixel value, this method is not scientific, when pushed to coordinate values of 0.75, should not take 1 is simple, the number is 0.25 smaller than 1. It is 0.75 larger than 0.

The target pixel value should be calculated according to the real points around the virtual point in the source graph, so as to achieve a better scaling effect.

  1. Optimization of the algorithm:

 I think of two optimization aspects:

  1. The first one is because the nearest neighbor interpolation algorithm to find the coordinates in the source image is fixed, we can put each target each x and each y corresponding value through a loop first to find out, and then enter the double loop. The speed of the program had been improved clearly.

The optimized codes are(in order to save the space, I only show the function part):

 

function put_img = Nearest_11711118(input_img, dim)

ima=imread(input_img);

imshow(ima);

title('In put Figure');



ima=double(ima);

swh=size(ima); %Get the width and height of the original image



inputWidth=swh(:,2); %Get the width  of the original image

inputHigh=swh(:,1); %Get the  height of the original image

r=dim(:,1);

c=dim(:,2);

outputHigh=ceil(inputHigh * c);

outputWidth=ceil(inputWidth * r);

resIma=zeros(outputHigh,outputWidth);

orignalx = [1:outputHigh];

orignaly = [1:outputWidth];

for i=1:outputHigh

    orignalx(i)=round(i/r);

end

for j=1:outputWidth

    orignaly(j)=round(j/c);

end

for i=1:outputHigh

    for j=1:outputWidth

      

        if(orignalx(i) < 1) %If the coordinates cross the border, make adjustments

                        orignalx(i) = 1;

        end

        if(orignalx(i) > inputHigh)

            orignalx(i) = swh;

        end

        if(orignaly(j) < 1)

            orignaly(j) = 1;

        end

        if(orignaly(j) > inputWidth)

            orignaly(j) = inputWidth;

        end

        resIma(i,j)=ima(orignalx(i),orignaly(j)); %The Grayscale of the position of the scaled image coordinate at the original image is assigned to the scaled image

    end

end

resIma=uint8(resIma);

figure;

imshow(resIma);

title('The Output Figure');

end
  1. The second is that using pointers is more efficient. This idea is come from the experience of C++, I think when I write this kind of data in C++, I will use pointer. But in matlab, I can not use pointer so far. I will do this idea in the feature.

 

  1. Use bilinear interpolation to interpolate a grey scale image:
  1. Introduction of the bilinear interpolation algorithm:

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第6张图片

Figure 6 example of bilinear interpolation

 

The key idea is to perform linear interpolation first in one direction, and then again in the other direction.

If we want to know the value of the unknown function f at the point P = (x, y), let's say we know the value of the function f at the points Q11 = (x1, y1), Q12 = (x1, y2), Q21 = (x2, y1), and Q22 = (x2, y2).

First, perform linear interpolation in the x direction, and get:

And then we do linear interpolation in the y direction, and we can get:

So that, the value of 

Pseudo code of the algorithm:

Input: original image :img, scaling factor:dim

Output: output image,

  1. Get the size of Img, denoted as height * width , and then generate the full 0 matrix new_img of (dim.height) * (dim. width) l; 
  2. Extend the Img boundary the size is (height+2) * (width+2); 
  3. For a pixel position (zi,zj) in the new scaled image new_img, map back to (zi/ dim.height,zj/ dim. width) and get (x,y) in the original image Img, since (x,y) is not set as an integer, so round down to get (i,j), where x = i + u,y = j + v.
  4. Calculate the value of f(zi,zj) by bilinear interpolation according to the following formula, that is,

f (x, y) = (1 - u) * (1 - v) * f (I, j) + (1 - u) * v * f (I, j + 1) + u * (1 - v) * f (I + 1, j) + u * v * f (I + 1, j + 1);.

  1. Repeat  3-4 until the matrix new_img is replaced.

 

  1. Matlab codes:
clear;

close all;

clc;

img = imread('rice.tif');

[ori,img_new] = Bilinear_11711118(img,[0.8,0.8]);

show(ori,img_new);



function show(original,new_img)

[height,width] = size(original);

figure;imshow(original);

axis on

title(['Input Figure with Size(',num2str(height),'*',num2str(width),'):']);

[new_height,new_width,] =size(new_img);

figure;imshow(new_img);

axis on

title(['Output Figure with Size( ',num2str(new_height),'*',num2str(new_width),'):']);

end



function [ original,new_img ] = Bilinear_11711118( original,dim )



[height,width] = size(original);

new_height = round(height*dim(:,1)); % Calculate the height of the scaled image

new_width = round(width*dim(:,2)); % %calculates the width of the scaled image

new_img = zeros(new_height,new_width);



%%Extend the size of matrix

img_scale = zeros(height+2,width+2);

img_scale(2:height+1,2:width+1,:) = original;

%%assigns values to the extended edges

img_scale(1,2:width+1,:) = original(1,:,:);

img_scale(height+2,2:width+1,:) = original(height,:,:);

img_scale(2:height+1,1,:) = original(:,1,:);

img_scale(2:height+1,width+2,:) = original(:,width,:);

%%assign values to the extended four vertices

img_scale(1,1,:) = original(1,1,:);

img_scale(1,width+2,:) = original(1,width,:);

img_scale(height+2,1,:) = original(height,1,:);

img_scale(height+2,width+2,:) = original(height,width,:);

for zj = 1:new_width       

    for zi = 1:new_height

        %  (zi,zj) represents the coordinates in the new diagram

        % ( ii,jj) represents the coordinates in the original diagram

        ii = (zi-1)/dim(:,1); jj = (zj-1)/dim(:,2);

        i = floor(ii); j = floor(jj);

        u = ii - i; v = jj - j;     

        i = i + 1; j = j + 1;

        new_img(zi,zj,:) = (1-u)*(1-v)*img_scale(i,j,:) + u*(1-v)*img_scale(i,j+1,:)...

                    + (1-u)*v*img_scale(i+1,j,:) + u*v*img_scale(i+1,j+1,:);

    end

end

new_img = uint8(new_img);

  

end 


 

  1. The output figure of the program:

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第7张图片

Figure 7 shrinked figure

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第8张图片

Figure 8 enlarged figure

 

  1. Analysis and conclusions:

The image quality of the bilinear interpolation algorithm is high. The greyscale is continuous. However, this algorithm has the property of low-pass filter, which damages the high-frequency components, so the image contour may be blurred to some extent.

Then we take a closer look at our pictures to verify the Analysis:

and we can see that the figure contour is blurred to some extent.

[数字图像处理]最近邻插值和双线性插值(nearest neighbor interpolation and bilinear interpolation)实验报告_第9张图片

Figure 9 closer look of enlarged figure

 

  1. Optimization of algorithm:

I think of two optimization aspects:

  1. Alignment of the geometric centers of the origin figure and target figure:
  1. Method: when calculating the floating point coordinates of the source image:

SrcX = dstX * (srcWidth/dstWidth),

SrcY = dstY * (srcHeight/dstHeight)

Center alignment:

SrcX = (dstX + 0.5) * (srcWidth/dstWidth) to 0.5

SrcY = (dstY + 0.5) * (srcHeight/dstHeight) to 0.5

  1. proof:

SrcX =dstX* (srcWidth/dstWidth)+0.5*(srcWidth/dstWidth-1)

This is equivalent to adding 0.5*(srcWidth/dstWidth-1) to the original floating point coordinates. The symbol can be positive or negative, depending on the ratio of srcWidth/dstWidth. Let's take an example: suppose the source image is 3*3, the center point coordinate (1,1) and the target image is 9*9, and the center point coordinate (4,4). When we do the interpolation, we want to use the pixel information of the source image as evenly as possible. The most intuitive is that (4,4) maps to (1,1). That is srcX=4*3/9=1.3333=1, the pixels we used in the interpolation are concentrated in the lower right of the image, rather than evenly distributed throughout the image. Now consider center alignment, srcX=(4+0.5)*3/9-0.5=1, which just meets our requirements.

你可能感兴趣的:(数字图像处理)