【问题标题】:Matlab: resize with custom interpolation kernel Mitchell-NetravaliMatlab:使用自定义插值内核 Mitchell-Netravali 调整大小
【发布时间】:2017-06-16 16:04:39
【问题描述】:

我看到有人对用于调整大小的自定义插值内核感兴趣 (MATLAB imresize with a custom interpolation kernel)。有没有人实现了 ImageMagick 中默认使用的参数化 Mitchell-Netravali 内核 [1] 并愿意分享 Matlab 代码?非常感谢!

[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;
 }
}

【问题讨论】:

    标签: matlab image-processing resize interpolation


    【解决方案1】:

    这里我找到了另一种矢量化方法;根据我的放大测试(1000x1000 -> 3000x3000),即使米切尔半径 = 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
    

    【讨论】:

    • 是的,矢量化通常比非矢量化更快。您可以从此函数中删除 find 以进一步提高速度。
    【解决方案2】:

    我得到了以下关于由 imresize 调用的 Mitchel 内核的建议,其中参数 B 和 C 以及使用 for 循环(和预分配)的内核半径:

    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
    

    【讨论】:

      猜你喜欢
      • 2011-12-23
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多