我主要參考了這里,不過他推導的系數我感覺有問題,用他的公式直接套用放大的圖像會有網格,也許是我理解的有偏差。
所以我自己重新推導了這四個系數

用這個就沒問題了。他的那些代碼還是很有參考價值的。
程序代碼:
main.m
clear all; close all; clc; w=2; %放大或縮小的寬度 h=2; %放大或縮小的高度 img=imread('lena.jpg'); %imshow(img); [m n]=size(img); imgn=zeros(h*m,w*n); rot=[h 0 0;0 w 0;0 0 1]; %變換矩陣x=h*u,y=w*v 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)); if pix(1) < 2 %邊界處理,也可以用卷積時常用的邊界擴展防止越界 pix(1) = 2; end if pix(1) > m-2 pix(1) = m-2; end if pix(2) < 2 pix(2) =2; end if pix(2) > n-2 pix(2) =n-2; end pix_up=floor(pix(1)); pix_left=floor(pix(2)); p=img(pix_up-1:pix_up+2,pix_left-1:pix_left+2); imgn(i,j)=bicubicInterpolate(p,float_X+1,float_Y+1); end end figure,imshow(uint8(imgn))
bicubicInterpolate.m
function re=bicubicInterpolate(p,x,y) %先行插值,再列插值 arr=zeros(4,1); for i=1:4 arr(i)=cubicInterpolate(p(i,1:4),x); end re= cubicInterpolate(arr,y); end
cubicInterpolate.m
function re=cubicInterpolate(p,x) p=double(p); % re=p(2) + 0.5 * x*(p(3) - p(1) + x*(2.0*p(1) - 5.0*p(2) + 4.0*p(3) - p(4) + x*(3.0*(p(2) - p(3)) + p(4) - p(1)))); a=(p(4)-3*p(1)+3*p(2)-p(1))/10; b=(p(3)-2*p(2)+p(1))/2-2*a; c=p(2)-p(1)-a-b; d=p(1); re=a*x^3+b*x^2+c*x+d; end
效果圖:
原圖
雙立方插值效果
雙線性插值效果
區別不大,不過認真看雙立方還是效果好些。
