只是根据自己的理解补充一下,参考文章来源:
图像放大并进行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个像素点的加权叠加。
根据比例关系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函数中的参数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):
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