图像缩放插值算法以及matlab简单实现(最近邻法、双线性插值法、三次卷积法)

主要有两个代码,一个是主代码,包括注释,另一个是cubic_factor函数,用于计算距离系数的。

clear;

close all;  

clc;





CONST=50;

A=imread('testImage\hyf1.bmp');

bwimg=im2bw(A);

resize_img=[];

[srcWidth srcHeight]=size(bwimg);





% %

% 以下算法思路参考http://blog.csdn.net/ArtX/article/details/1540539和http://blog.csdn.net/qiqi5521/article/details/2207562这两篇博客,谢谢博主。

% % 最近邻

% % 思想是根据 srcWidth/dstWidth = srcX/dstY,最后再对srcX取整

% % 缺点是精度不够,严重失真

% 

% dstWidth=srcWidth+CONST*2;

% dstHeight=srcHeight+CONST*2;

% resize_img=zeros(dstWidth,dstHeight);

% 

% % 像素变化公式计算公式

% for i=1:dstWidth

%     for j=1:dstHeight

%     src_i=i*(srcWidth/dstWidth);

%     src_j=j*(srcHeight/dstHeight);

%     resize_img(i,j)=bwimg(round(src_i),round(src_j)); % round四舍五入

%     end

% end

% 

% figure,imshow(bwimg);

% figure,imshow(resize_img)



% % 双线性内插值算法

% % 聪明的方法

% % 最近邻法中根据 srcWidth/dstWidth = srcX/dstY,可以倒退出一个srcX的坐标值,但是这个值是浮点数,

% % 这个浮点数提供了一些信息,它离它在原始图像四周的像素值的关系,根据这个关系,计算一个更接近的dstX,

% % 然后再填充目标图像

% % 公式:

% % f(i+u,j+v)=(1-u)(1-v)f(i,j)+(1-u)vf(i,j+1)+u(1-v)f(i+1,j)+uvf(i+1,j+1)

% % i,j 为浮点坐标的整数部分; u,v为浮点坐标的小数部分

% % 优点:缩放后图像质量高

% % 缺点: 计算量大,双线性插值具有低通滤波器的性质,使高频分量受损,图像轮廓在一定程度上变模糊

% 

% dstWidth=srcWidth+CONST*2;

% dstHeight=srcHeight+CONST*2;

% resize_img=zeros(dstWidth,dstHeight);

% 

% % 像素变化公式计算公式

% for i=1:dstWidth-1

%     for j=1:dstHeight-1

%     src_i=i*(srcWidth/dstWidth);

%     src_j=j*(srcHeight/dstHeight);

%     src_ii=fix(src_i);

%     src_iu=src_i - src_ii; % none fix part

%     src_jj=fix(src_j);

%     src_jv=src_j - src_jj;

%     if src_ii == 0 

%         src_ii=src_ii+1;

%     end

%     if src_jj ==0 

%         src_jj=src_jj+1;

%     end

%     resize_img(i,j)=(1-src_iu)*(1-src_jv)*bwimg(src_ii,src_jj)+(1-src_iu)*src_jv*bwimg(src_ii,src_jj+1)+src_iu*(1-src_jv)*bwimg(src_ii+1,src_jj)...

%         +src_iu*src_jv*bwimg(src_ii+1,src_jj+1);

%     end

% end

% figure,imshow(bwimg);

% figure,imshow(resize_img)





% 三次卷积法

% 三次卷积法计算精度高,但计算亮大,思路是根据一个浮点坐标(i+u,j+v)周围的16个邻点,由下列公式得出目的像素值f(i+u,j+v):

% 

%     f(i+u,j+v) = [A] * [B] * [C]

% 

% [A]=[ S(u + 1) S(u + 0) S(u - 1) S(u - 2) ]

% 

%   ┏ f(i-1, j-1) f(i-1, j+0) f(i-1, j+1) f(i-1, j+2) ┓

% [B]=┃ f(i+0, j-1) f(i+0, j+0) f(i+0, j+1) f(i+0, j+2) ┃

%   ┃ f(i+1, j-1) f(i+1, j+0) f(i+1, j+1) f(i+1, j+2) ┃

%   ┗ f(i+2, j-1) f(i+2, j+0) f(i+2, j+1) f(i+2, j+2) ┛

% 

%   ┏ S(v + 1) ┓

% [C]=┃ S(v + 0) ┃

%   ┃ S(v - 1) ┃

%   ┗ S(v - 2) ┛

% 

%    ┏ 1-2*Abs(x)^2+Abs(x)^3      , 0<=Abs(x)<1

% S(x)={ 4-8*Abs(x)+5*Abs(x)^2-Abs(x)^3 , 1<=Abs(x)<2

%    ┗ 0                , Abs(x)>=2

% 有人说,S(x)是对 Sin(x*Pi)/x

% 的逼近(Pi是圆周率——π),通过极限计算,可以知道Sin(x*Pi)/x的范围在0~pi之间,无法理解为什么要这样设置S(x)

% 但上述求A、B、C的公式还是可以理解,根据双线性插值的思想,也就是根据浮点数在原始坐标中与邻近像素的距离远近来决定原始坐标在目的坐标中所占的比重





dstWidth=srcWidth-CONST*2;

dstHeight=srcHeight-CONST*2;

resize_img=zeros(dstWidth,dstHeight);

A=[];B=[];C=[];





% 像素变化公式计算公式

for i=3:dstWidth-2

    for j=3:dstHeight-2

    src_i=i*(srcWidth/dstWidth);

    src_j=j*(srcHeight/dstHeight);

    src_ii=fix(src_i); % 整数部分

    src_iu=src_i - src_ii; % 小数部分

    src_jj=fix(src_j);

    src_jv=src_j - src_jj;

    

    A=[ cubic_factor(src_iu+1) cubic_factor(src_iu) cubic_factor(src_iu-1) cubic_factor(src_iu-2) ];

    C=[ cubic_factor(src_jv+1); cubic_factor(src_jv); cubic_factor(src_jv-1); cubic_factor(src_jv-2) ];

    B=[ bwimg(src_ii -1,src_jj -1) bwimg(src_ii-1,src_jj) bwimg(src_ii-1,src_jj+1) bwimg(src_ii-1,src_jj+2);...

        bwimg(src_ii,src_jj-1) bwimg(src_ii,src_jj) bwimg(src_ii,src_jj+1) bwimg(src_ii,src_jj+2); ...

        bwimg(src_ii+1,src_jj-1) bwimg(src_ii+1,src_jj) bwimg(src_ii+1,src_jj+1) bwimg(src_ii+1,src_jj+2); ...

        bwimg(src_ii+2,src_jj-1) bwimg(src_ii+2,src_jj) bwimg(src_ii+2,src_jj+1) bwimg(src_ii+2,src_jj+2) ];

    

    resize_img(i,j)=A*B*C;

    

 

    end

end



figure,imshow(bwimg);

figure,imshow(resize_img)





% dstimg=imresize(srcimg,4,'bicubic'); % matlab库函数,调用imresize可以重新生成不同尺寸的图片

 

cubic_factor函数

% 距离系数计算公式

%    ┏ 1-2*Abs(x)^2+Abs(x)^3      , 0<=Abs(x)<1

% S(x)={ 4-8*Abs(x)+5*Abs(x)^2-Abs(x)^3 , 1<=Abs(x)<2

%    ┗ 0                , Abs(x)>=2

function S=cubic_factor(x)



if 0<=abs(x)<1

    S=1-2.*abs(x).^2+abs(x).^3;

elseif 1<=abs(x)<2

    S=4-8.*abs(x)+5.*abs(x).^2-abs(x).^3;

else

    S=0;

end

 

 

上面代码有一个问题,”最右边和最下边的像素实际上并没有参与计算“,似乎是由于最初的中心点选择方法引起的,网上有一个人提出了解决方案(http://handspeaker.iteye.com/blog/1545126),看了一下,大概了解他的想法,试验之后,没有效果,可能我理解错了,下次再来解决这个问题并修改代码吧。

 

你可能感兴趣的:(matlab)