双三次插值(BiCubic插值)

 只是根据自己的理解补充一下,参考文章来源:

 图像缩放之双三次插值法 点击打开链接

 图像放大并进行BiCubic插值 Matlab/C++代码点击打开链接

 假设源图像A大小为m*n,缩放K倍后的目标图像B的大小为M*N,即K=M/m。A的每一个像素点是已知的,B是未知的,我们想要求出目标图像B中每一像素点(X,Y)的值,必须先找出像素(X,Y)在源图像A中对应的像素(x,y),再根据源图像A距离像素(x,y)最近的16个像素点作为计算目标图像B(X,Y)处像素值的参数,利用BiCubic基函数求出16个像素点的权重,图B像素(x,y)的值就等于16个像素点的加权叠加。

双三次插值(BiCubic插值)_第1张图片

 根据比例关系x/X=m/M=1/K,我们可以得到B(X,Y)在A上的对应坐标为A(x,y)=A(X*(m/M),Y*(n/N))=A(X/K,Y/K)。如图所示P点就是目标图像B在(X,Y)处对应于源图像A中的位置,P的坐标位置会出现小数部分,所以我们假设 P的坐标为P(x+u,y+v),其中x,y分别表示整数部分,u,v分别表示小数部分(蓝点到a11方格中红点的距离)。那么我们就可以得到如图所示的最近16个像素的位置,在这里用a(i,j)(i,j=0,1,2,3)来表示,如上图。

 双三次插值(BiCubic插值)_第2张图片

 我们要做的就是求出BiCubic函数中的参数x,从而获得上面所说的16个像素所对应的权重W(x)。BiCubic基函数是一维的,而像素是二维的,所以我们将像素点的行与列分开计算。BiCubic函数中的参数x表示该像素点到P点的距离,例如a00距离P(x+u,y+v)的距离为(1+u,1+v),因此a00的横坐标权重i_0=W(1+u),纵坐标权重j_0=W(1+v),a00对B(X,Y)的贡献值为:(a00像素值)* i_0* j_0。因此,a0X的横坐标权重分别为W(1+u),W(u),W(1-u),W(2-u);ay0的纵坐标权重分别为W(1+v),W(v),W(1-v),W(2-v);B(X,Y)像素值为:


上述可以用矩阵形式表示,下面图片来源:点击打开链接

加权算法(a可以不取-0.5):

双三次插值(BiCubic插值)_第3张图片


clc,clear;
ff=imread('C:\Users\Administrator\Desktop\1.jpg');           %读取图像到ff
k=8;                       %设置放大倍数
[m,n,color]=size(ff);  
f=zeros(m,n);      %将彩色图像ff转换为黑白图像f
for i=1:m
    for j=1:n
        f(i,j)=ff(i,j);
    end
end
a=f(1,:);
c=f(m,:);             %将待插值图像矩阵前后各扩展两行两列,共扩展四行四列,当插值点为边沿点时候,确保周围有16个点
b=[f(1,1),f(1,1),f(:,1)',f(m,1),f(m,1)];
d=[f(1,n),f(1,n),f(:,n)',f(m,n),f(m,n)];
a1=[a;a;f;c;c];
b1=[b;b;a1';d;d];
f=b1';
f1=double(f);
for i=1:k*m                 %利用双三次插值公式对新图象所有像素赋值
  u=rem(i,k)/k;            %rem取余,取余后再除以k是因为u为小数,自己代数字验证一下
  i1=floor(i/k)+2;   %i1为B(X,Y)对应A(x,y)的横坐标整数部分,加2是因为上面扩大了四行四列,要回到原来图像的点再计算。
  A=[sw(1+u) sw(u) sw(1-u) sw(2-u)];   %四个横坐标的权重W(i)
  for j=1:k*n
    v=rem(j,k)/k;j1=floor(j/k)+2;   %纵坐标原理同上
    C=[sw(1+v);sw(v);sw(1-v);sw(2-v)]; %转置
    B=[f1(i1-1,j1-1)     f1(i1-1,j1)     f1(i1-1,j1+1)     f1(i1-1,j1+2)    %坐标P(x+u,y+v)最近的16个点的像素值
         f1(i1    ,j1-1)     f1(i1,   j1)     f1(i1,   j1+1)     f1(i1,   j1+2)
         f1(i1+1,j1-1)     f1(i1+1,j1)    f1(i1+1,j1+1)   f1(i1+1,j1+2)
         f1(i1+2,j1-1)     f1(i1+2,j1)    f1(i1+2,j1+1)   f1(i1+2,j1+2)];
    g1(i,j)=(A*B*C);
  end
end
g=uint8(g1); %将矩阵转换成8位无符号整数
imshow(g);
title('X8');


function A=sw(w1)
w=abs(w1);
a=-0.5;
if w<1&&w>=0
  A=1-(a+3)*w^2+(a+2)*w^3;
else if w>=1&&w<2
  A=a*w^3-5*a*w^2+(8*a)*w-4*a;
else
  A=0;
    end
end
end


你可能感兴趣的:(双三次插值(BiCubic插值))