here で説明されているように、画像のサイズ変更にバイキュービック補間を実装しようとしています。
Triangular または Bell カーネルを試すと、妥当な結果が得られます。しかし、B-Spline または CatMull-Rom カーネルを試してみると、このグリッドのようなアーティファクトが表示されます(左は CatMull-Rom、右は Bell)。私がしたことは、提供されたリンクの式から Rc 式を置き換えることだけでした。
それを引き起こしている可能性のあるアイデアはありますか?
編集:これは、matlabで行われたメイン関数のコードです
function J = bicubic_interpolation_v3(I, R, C, R_nove, C_nove)
% input:
% I .. 3 x R*C array with input pixels [ [r1;g1;b1] [r2;g2;b2]... ]
% R x C .. size of the original image
% R_nove x C_nove .. size of the resized image, R_nove<R, C_nove<C
%
% output:
% J .. 3 x R_nove*C_nove .. array with output pixels, same format as I
scaleR = (R-1) / (R_nove-1);
scaleC = (C-1) / (C_nove-1);
J = zeros(3, R_nove*C_nove);
helpin = 1;
for i=1:R_nove
for j=1:C_nove
r_nove_ve_starem = 1+scaleR*(i-1);
c_nove_ve_starem = 1+scaleC*(j-1);
r_nejblizsi_dole = floor( r_nove_ve_starem );
c_nejblizsi_dole = floor( c_nove_ve_starem );
% boundary pixels (not dealing with them yet)
if( r_nejblizsi_dole<2 || r_nejblizsi_dole>R-2 || ...
c_nejblizsi_dole<2 || c_nejblizsi_dole>C-2)
J(1,helpin) = 51;
J(2,helpin) = 255;
J(3,helpin) = 255;
helpin = helpin+1;
continue;
end
id1 = ( r_nejblizsi_dole-2 )*C + c_nejblizsi_dole-1;
id2 = ( r_nejblizsi_dole-2 )*C + c_nejblizsi_dole;
id3 = ( r_nejblizsi_dole-2 )*C + c_nejblizsi_dole+1;
id4 = ( r_nejblizsi_dole-2 )*C + c_nejblizsi_dole+2;
%
id5 = ( r_nejblizsi_dole-1 )*C + c_nejblizsi_dole-1;
id6 = ( r_nejblizsi_dole-1 )*C + c_nejblizsi_dole;
id7 = ( r_nejblizsi_dole-1 )*C + c_nejblizsi_dole+1;
id8 = ( r_nejblizsi_dole-1 )*C + c_nejblizsi_dole+2;
%
id9 = r_nejblizsi_dole*C + c_nejblizsi_dole-1;
id10 = r_nejblizsi_dole*C + c_nejblizsi_dole;
id11 = r_nejblizsi_dole*C + c_nejblizsi_dole+1;
id12 = r_nejblizsi_dole*C + c_nejblizsi_dole+2;
%
id13 = (r_nejblizsi_dole+1)*C + c_nejblizsi_dole-1;
id14 = (r_nejblizsi_dole+1)*C + c_nejblizsi_dole;
id15 = (r_nejblizsi_dole+1)*C + c_nejblizsi_dole+1;
id16 = (r_nejblizsi_dole+1)*C + c_nejblizsi_dole+2;
a = r_nove_ve_starem-r_nejblizsi_dole;
b = c_nove_ve_starem-c_nejblizsi_dole;
for k=1:3
J(k,helpin) = J(k,helpin) + ...
I(k,id1) *Rc(-1-a)*Rc(-(-1-b)) + I(k,id2) *Rc(-1-a)*Rc(-(-b)) + I(k,id3) *Rc(-1-a)*Rc(-(1-b)) + I(k,id4) *Rc(-1-a)*Rc(-(2-b))+ ...
I(k,id5) *Rc(-a) *Rc(-(-1-b)) + I(k,id6) *Rc(-a) *Rc(-(-b)) + I(k,id7) *Rc(-a) *Rc(-(1-b)) + I(k,id8) *Rc(-a) *Rc(-(2-b))+ ...
I(k,id9) *Rc(1-a) *Rc(-(-1-b)) + I(k,id10)*Rc(1-a) *Rc(-(-b)) + I(k,id11)*Rc(1-a) *Rc(-(1-b)) + I(k,id12)*Rc(1-a) *Rc(-(2-b))+ ...
I(k,id13)*Rc(2-a) *Rc(-(-1-b)) + I(k,id14)*Rc(2-a) *Rc(-(-b)) + I(k,id15)*Rc(2-a) *Rc(-(1-b)) + I(k,id16)*Rc(2-a) *Rc(-(2-b));
end
helpin = helpin + 1;
end
end
end
ここにカーネルがあります
function P = Rc( x )
% Bell kernel
if(x>=-1.5 && x<=-0.5)
P=0.5*(x+1.5)^2;
elseif( x>-0.5 && x<=0.5 )
P = 0.75-x^2;
elseif( x>0.5 && x<=1.5 )
P = 0.5*(x-1.5)^2;
else
P = 0;
end
end
function P = Rc2( x )
% CatMull-Rom
Be=0;
Ce=0.5;
s = abs(x);
if(s<1)
P = (12-9*Be-6*Ce)*s^3+(-18+12*Be+6*Ce)*s^2+(6-2*Be);
elseif( s>=1 && s<2 )
P = (-Be-6*Ce)*s^3+(6*Be+30*Ce)*s^2+...
(-12*Be-48*Ce)*s+(8*Be+24*Ce);
else
P = 0;
end
P = (1/6)*P;
end