0

I have seen that there was an interest in custom interpolation kernels for resize (MATLAB imresize with a custom interpolation kernel). Did anyone implemented the parametric Mitchell-Netravali kernel [1] that is used as default in ImageMagick and is willing to share the Matlab code? Thank you very much!

[1] http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch24.html

// Mitchell Netravali Reconstruction Filter
// B = 0    C = 0   - Hermite B-Spline interpolator 
// B = 1,   C = 0   - cubic B-spline
// B = 0,   C = 1/2 - Catmull-Rom spline
// B = 1/3, C = 1/3 - recommended

float MitchellNetravali(float x, float B, float C)
{
 float ax = fabs(x);
 if (ax < 1) {
 return ((12 - 9 * B - 6 * C) * ax * ax * ax +
        (-18 + 12 * B + 6 * C) * ax * ax + (6 - 2 * B)) / 6;
} else if ((ax >= 1) && (ax < 2)) {
  return ((-B - 6 * C) * ax * ax * ax +
          (6 * B + 30 * C) * ax * ax + (-12 * B - 48 * C) *
          ax + (8 * B + 24 * C)) / 6;
} else {
  return 0;
 }
}
Claude
  • 1,014
  • 7
  • 13

2 Answers2

1

Here I got another approach with vectorization; according to my tests with upscaling (1000x1000 -> 3000x3000) this is faster than the standard bicubic even with a large Mitchell radius = 6:

function [outputs] = Mitchell_vect(x,M_B,M_C)
   outputs= zeros(size(x,1),size(x,2)); 
   ax = abs(x);
   temp = ((12-9*M_B-6*M_C) .* ax.^3 + (-18+12*M_B+6*M_C) .* ax.^2 + (6-2*M_B))./6;
   temp2 = ((-M_B-6*M_C) .* ax.^3 + (6*M_B+30*M_C) .* ax.^2 + (-12*M_B-48*M_C) .* ax + (8*M_B + 24*M_C))./6;
   index = find(ax<1);
   outputs(index)=temp(index);
   index = find(ax>=1 & ax<2);
   outputs(index)=temp2(index);
end
  • Yes, vectorized is usually faster than non-vecotrized. You can remove `find` from this function for a further speed boost. – Cris Luengo Nov 25 '18 at 15:37
0

I got the following proposal for the Mitchel kernel called by imresize with the parameters B and C and a kernel radius using for-loops (and preallocation):

img_resize = imresize(img, [h w], {@(x)Mitchell(x,B,C),radius}); 

function [outputs] = Mitchell(x,B,C)
outputs= zeros(size(x,1),size(x,2)); 
    for i = 1 : size(x,1)
        for j = 1 : size(x,2)
            ax = abs(x(i,j));
            if ax < 1
                outputs(i,j) = ((12-9*B-6*C) * ax^3 + (-18+12*B+6*C) * ax^2 + (6-2*B))/6;
            elseif (ax >= 1) && (ax < 2)
                outputs(i,j) = ((-B-6*C) * ax^3 + (6*B+30*C) * ax^2 + (-12*B-48*C) * ax + (8*B + 24*C))/6;
            else 
                outputs(i,j) = 0;
            end
        end
    end
end