【问题标题】:Interpolate/fill in missing cells in truth-value grid in MATLAB在 MATLAB 中插入/填充真值网格中的缺失单元格
【发布时间】:2014-03-05 16:01:39
【问题描述】:

考虑下面的 37x101 矩阵:

每个黑色单元格的值为 1,其余单元格的值为 0。我想通过三次样条插值以及将 y 轴从 37 缩放到 181 来填充“间隙”。后者可以通过使用 interp1 函数来完成,如:

interp1(37,matrix,181,'pchip')

但是,结果现在沿 y 轴插值,但仍然存在差距:

我不想沿 x 轴进行插值,因为我希望最终矩阵的尺寸为 181 x 101。我只想使用现有单元格(181 x 101 矩阵)填补空白。

如何将原始矩阵(顶部)从 37 x 101 缩放到 181 x 101(第二张图像中没有“平滑”),以及使用某种样条插值填充间隙,就像这样是一个适当的功能吗?

【问题讨论】:

    标签: matlab matrix interpolation


    【解决方案1】:

    您的真值网格似乎只有一个,其中真值在每一行中。如果 true/1 值确实在图像中创建了一条线,我建议将这条线参数化为 t,以便 y = fy(t)x = fx(t)。如果您对此不熟悉,可以在 youtube 教程或 google 上找到一些参数化信息。主要思想是,如果您有 ,请说出如下所示的真值表:

    然后您可以绘制每个像素相对于另一个变量t 的位置,然后在每个变量上单独使用interp1(...)。就我而言,我将 x 和 y 值定义如下:

    n = 32;
    rand('seed', 1982);
    y_orig = 1:n;
    x_orig = ceil(n*sin(y_orig/n*pi));
    

    所以我可以绘制为:

    t1 = linspace(0,1, n);
    plot(t1,x_orig, 'r', 'linewidth', 3);
    hold all
    plot(t1,y_orig, 'b', 'linewidth', 3);
    legend('X', 'Y')
    

    请注意,我可以像这样使用 interp1 得到任何我想要的真值(如果你想在第 5 行和第 6 行之间找到值):

     desiredY = 5.5;
     t= 1:n;
     truthValue= interp1(t, x_orig, desiredY, 'cubic')
    

    但是我们正在寻找一个新的图像,所以我选择了一个更方便的参数化 t 介于 0 和 1 之间。不幸的是,您可能手头没有 x 和 y,因此我们需要将它们从图像中拉出。假设您在每一行中都有一个 true/1 值,我们可以使用 max(...) 抽出这些值:

    [maxVals, x1] = max(data,[],2);
    x1(maxVals == 0) = [];
    y1 = find(maxVals ~= 0);
    

    每行上的某种形式的find 也可以使用。如果每一行都有一个真值,那么y1 应该等于1:n。 max 函数在第二个返回值中返回最大维度 2 的索引。我使用接下来的两行删除真值表为空的所有条目(最大值为零),然后 y1 = 1:n 减去那些为空的条目。

    在这条线上获得大量分数的一种快速而肮脏的方法是:

    t2 = linspace(0,1,1024);
    x2 = interp1(t1, x1, t2, 'cubic');
    y2 = interp1(t1, y1, t2, 'cubic');
    

    然后我可以将原始点/图像和这条新发现的细线绘制在一起,如下所示:

    imagesc(data);
    hold all;
    plot(x2,y2, 'linewidth', 2);
    axis image
    colormap(flipud(colormap(gray)));
    

    要得到这个:

    最后,您可以通过放大参数化来快速将其转换为新图像。为了清晰起见,我的方法并不是特别有效:

    y2_scaled = floor((y2(:)-1)*scaleValue + 1);
    x2_scaled = floor((x2(:)-1)*scaleValue + 1);
    
    scaleValue = 2;
    data2 = zeros(n*scaleValue);
    for ind = 1:length(x2_scaled)
        data2(y2_scaled(ind),x2_scaled(ind)) = 1;
    end
    

    结果:

    请注意,此表已连接所有点,现在每行中有多个 true/1。这是因为我为 t2 选择了一个非常小的步长。您可以通过更智能地选择 t2、跳过每行中的多个值或平均每行中每个索引的位置来解决此问题。或者忽略这个问题。

    要使用缩放值修复t2,您可以使用

    t2 = linspace(0,1,n*scaleValue);
    

    在上面的代码中每行只得到一个 true/1。

    另外,如果你只想缩放一个维度,你可以这样做:

    y2_scaled = floor((y2(:)-1)*scaleValue + 1);
    x2_scaled = floor((x2(:)-1) + 1);
    
    scaleValue = 2;
    data2 = zeros(n*scaleValue,n);
    for ind = 1:length(x2_scaled)
        data2(y2_scaled(ind),x2_scaled(ind)) = 1;
    end
    

    【讨论】:

    • 史蒂夫,这太棒了。每行中的多个真值不是问题。谢谢!
    【解决方案2】:

    我将其视为位图,那为什么不是钳位模糊呢?

    I=yourmatrixhere
    
    %gaussian blur
    %    it looks like bump-to-bump distance is 3 empties
    %    therefore hsize should be about 7
    %    it looks like bump vertical size is about 4
    %    therefore simga should be about 10
    
    hsize=[3 3];
    sigma = 10;
    h=fspecial('gaussian',hsize,sigma)
    
    I2=imfilter(I,h,'replicate');
    

    此时您已经将信息传播到相邻的列,但您需要“整理”从连续到二进制。

    %threshold
    th = 0.25;
    
    I3=zeros(size(I));
    ind=find(I>=th);
    I3(ind)=1;
    

    此时,I3 是您感兴趣的矩阵,可以进行“侵蚀”或插值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 2020-12-14
      • 1970-01-01
      相关资源
      最近更新 更多