0

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
4

0 に答える 0