imresize - trying to understand the bicubic interpolation

前端 未结 2 1003
终归单人心
终归单人心 2020-12-03 06:05

I\'m trying to understand the function:

function [weights, indices] = contributions(in_length, out_length, ...
                                            sc         


        
2条回答
  •  我在风中等你
    2020-12-03 06:46

    imresize accomplishes anti-aliasing when downsizing an image by simply broadening the cubic kernel, rather than a discrete pre-processing step.

    For a kernel_width of 4 pixels (8 after re-scaled), where the contributions function utilizes 10 neighbors for each pixel, the kernel vs h (scaled kernel) look like (unnormalized, ignore x-axis):

    enter image description here

    This is easier than first performing a low-pass filter or Gaussian convolution in a separate pre-processing step.

    The cubic kernel is defined at the bottom of imresize.m as:

    function f = cubic(x)
    % See Keys, "Cubic Convolution Interpolation for Digital Image
    % Processing," IEEE Transactions on Acoustics, Speech, and Signal
    % Processing, Vol. ASSP-29, No. 6, December 1981, p. 1155.
    
    absx = abs(x);
    absx2 = absx.^2;
    absx3 = absx.^3;
    
    f = (1.5*absx3 - 2.5*absx2 + 1) .* (absx <= 1) + ...
                    (-0.5*absx3 + 2.5*absx2 - 4*absx + 2) .* ...
                    ((1 < absx) & (absx <= 2));
    

    PDF of the referenced paper.

    The relevant part is equation (15):

    enter image description here

    This is a specific version of the general interpolation equations for a = -0.5 in the following equations:

    enter image description here

    a is usually set to -0.5, or -0.75. Note that a = -0.5 corresponds to the Cubic Hermite spline, which will be continuous and have a continuous first derivitive. OpenCV seems to use -0.75.

    However, if you edit [OPENCV_SRC]\modules\imgproc\src\imgwarp.cpp and change the code :

    static inline void interpolateCubic( float x, float* coeffs )
    {
        const float A = -0.75f;
        ...
    

    to:

    static inline void interpolateCubic( float x, float* coeffs )
    {
        const float A = -0.50f;
        ...
    

    and rebuild OpenCV (tip: disable CUDA and the gpu module for short compile time), then you get the same results. See the matching output in my other answer to a related question by the OP.

提交回复
热议问题