Octave Matlab中的三维矩阵插值

Octave Matlab中的三维矩阵插值,octave,interpolation,matlab,Octave,Interpolation,Matlab,我在Matlab中有一个特定大小的3D矩阵,但是我需要对其进行插值以获得更大的矩阵 size(M) ans= 50 108 86 我需要对该矩阵进行插值,并最终获得大小为100x213x140的矩阵。关于如何使用interp3进行此操作,您有什么想法吗?这可能吗 我试过了 Vq = interp3(M,1:100,1:213,1:140) Error using griddedInterpolant/subsref The input data has inconsistent

我在Matlab中有一个特定大小的3D矩阵,但是我需要对其进行插值以获得更大的矩阵

size(M)
ans= 
  50   108    86
我需要对该矩阵进行插值,并最终获得大小为100x213x140的矩阵。关于如何使用
interp3
进行此操作,您有什么想法吗?这可能吗

我试过了

Vq = interp3(M,1:100,1:213,1:140)
Error using griddedInterpolant/subsref
The input data has inconsistent size.

Error in interp3 (line 178)
    Vq = F(Xq,Yq,Zq);
如果我使用
meshgrid

[X,Y,Z] = meshgrid(1:100, 1:213, 1:140);
Vq =interp3(M,X,Y,Z);
Matlab似乎很喜欢它,但有两件事发生了:

  • size(Vq)ans=213 100 140
  • 我可以在
    Vq

  • 背后的原因是因为我需要比较以不同频率采样的两个矩阵。因此,我可以插值
    M
    以获得大小为
    100x213x140
    的矩阵,或者将另一个大小为
    100x213x140
    的矩阵
    M2
    的大小“减小”为
    50x108x86
    。我认为前者应该更容易、更安全……

    你几乎说对了。您需要定义坐标的三维网格。创建单个向量不是正确的方法。您当然可以在这里使用
    interp3
    。试着做:

    [X,Y,Z] = meshgrid(1:213, 1:100, 1:140);
    Vq = interp3(M, X, Y, Z);
    
    请注意,我已经交换了行(100)和列(213)限制,因为第一个参数水平前进,而第二个参数垂直前进

    此外,通过以这种方式使用
    interp3
    ,我们假设
    X
    Y
    Z
    的限制在
    1:213
    1:100
    1:140
    范围内。如果您提供的值超出这些限制,您将得到
    NaN
    。有几种方法可以避免这种情况:

  • 在末尾指定
    样条曲线
    标志以允许样条曲线外推
  • 如果要调整矩阵的大小(如调整图像大小),则当前没有内置方法可以通过这种方式调整三维矩阵的大小。这是你自己写的 如果要执行步骤2,可以执行以下操作

    首先,您需要计算每个维度的比例因子。基本上,这是每个维度的输出大小与原始输入大小的比率

    在此之后,将创建一个二维栅格,其限制由输入矩阵的原始大小限定,但该栅格的大小将与输出矩阵的大小相同。比例因子在这里很有用,因为它有效地为我们提供了网格中每个值应该插值的内容。我们将创建从1到每个维度输出大小的新坐标,增量为
    1/scaleFactor
    。例如,如果我们想将矩阵的大小增加一倍,这是一个系数2。如果我们的
    X
    Y
    坐标分别从1到3和1到3,原始网格将如下所示:

    X =            Y = 
    
    1  2  3        1  1  1
    1  2  3        2  2  2
    1  2  3        3  3  3
    
    要使这一数字翻倍,这将是:

    X =                         Y = 
    
    1  1.5  2  2.5  3           1   1   1   1   1
    1  1.5  2  2.5  3          1.5 1.5 1.5 1.5 1.5
    1  1.5  2  2.5  3           2   2   2   2   2
    1  1.5  2  2.5  3          2.5 2.5 2.5 2.5 2.5 
    1  1.5  2  2.5  3           3   3   3   3   3
    
    请注意,这将创建一个5 x 5的输出网格。要使其加倍为6 x 6,您可以做任何您想做的事情,但为了简单起见,只需复制最后一行和最后一列,因此:

    X =                         Y = 
    
    1  1.5  2  2.5  3  3         1   1   1   1   1   1
    1  1.5  2  2.5  3  3        1.5 1.5 1.5 1.5 1.5 1.5
    1  1.5  2  2.5  3  3         2   2   2   2   2   2
    1  1.5  2  2.5  3  3        2.5 2.5 2.5 2.5 2.5 2.5
    1  1.5  2  2.5  3  3         3   3   3   3   3   3
    1  1.5  2  2.5  3  3         3   3   3   3   3   3
    
    这定义了用于调整大小的二维列网格。现在的问题是在3D中调整大小。我们可以做的是在切片之间插入。我们可以在MATLAB中使用
    permute
    轻松地完成这项工作,稍后我将向您展示如何完成这项工作。因此,基本算法如下:

    • 确定所需输出矩阵的输出大小
    • 确定每个维度中的比例因子
    • 按照上述步骤为每个标注创建插值访问值的二维栅格
    • 对于矩阵中的每个二维切片,使用
      interp2
      使用上述二维网格根据输出行和列调整每个切片的大小
    • 之后,使用
      interp1
      permute
      调整三维尺寸

    无需进一步说明,以下是执行此操作的代码:

    %// Specify output size of your matrix here
    outputSize = [100 213 140];
    
    %//Figure out size of original matrix
    d = size(M);
    
    %//Scaling coefficients
    scaleCoeff = outputSize ./ d;
    
    %//Indices of original slices in 3D
    z = 1:d(3);
    
    %//Output slice indices in 3D
    zi=1:1/scaleCoeff(3):d(3);
    
    %//Create gridded interpolated co-ordinates for 1 slice
    [X,Y] = meshgrid(1:1/scaleCoeff(2):d(2), 1:1/scaleCoeff(1):d(1));
    
    %//We simply duplicate the last rows and last columns of the grid if
    %//by doing meshgrid, we don't get exactly the output size we want
    %//This is due to round off when perform 1/scaleCoeff(2) or
    %//1/scaleCoeff(1).  We would be off by 1.
    if size(X,1) ~= outputSize(1)
        X(end+1,:) = X(end,:);
        Y(end+1,:) = Y(end,:);
    end
    if size(X,2) ~= outputSize(2)
        X(:,end+1) = X(:,end);
        Y(:,end+1) = X(:,end);
    end
    
    %//For each slice...
    M2D = zeros(outputSize(1), outputSize(2), d(3));
    for ind = z
        %//Interpolate each slice via interp2
        M2D(:,:,ind) = interp2(M(:,:,ind), X, Y);
    end
    
    %//Now interpolate in 3D
    MFinal = permute(interp1(z,permute(M2D,[3 1 2]),zi),[2 3 1]);
    
    %//If the number of output slices don't match after we interpolate in 3D, we
    %//just duplicate the last slice again
    if size(MFinal,3) ~= outputSize(3)
        MFinal(:,:,end+1) = MFinal(:,:,end);
    end
    


    MFinal
    将是最终插值/调整大小的3D矩阵。三维插值的关键方法是
    permute
    方法。这将为
    z
    的每个值生成一个2D值片。因此,如果我们在
    z=1
    处有一个切片,在
    z=2
    处有一个切片,如果我们想找到切片
    z=1.5
    处的2D值网格,这将生成一个2D切片,该切片使用
    z=1
    z=2
    之间的信息创建这些插值。我们首先调用
    permute
    来执行此操作,然后调用另一个
    permute
    来撤消我们的排列并恢复原始维度。

    您几乎完全正确。您需要定义坐标的三维网格。创建单个向量不是正确的方法。您当然可以在这里使用
    interp3
    。试着做:

    [X,Y,Z] = meshgrid(1:213, 1:100, 1:140);
    Vq = interp3(M, X, Y, Z);
    
    请注意,我已经交换了行(100)和列(213)限制,因为第一个参数水平前进,而第二个参数垂直前进

    此外,通过以这种方式使用
    interp3
    ,我们假设
    X
    Y
    Z
    的限制在
    1:213
    1:100
    1:140
    范围内。如果您提供的值超出这些限制,您将得到
    NaN
    。有几种方法可以避免这种情况:

  • 在末尾指定
    样条曲线
    标志以允许样条曲线外推
  • 如果要调整矩阵的大小(如调整图像大小),则当前没有内置方法可以通过这种方式调整三维矩阵的大小。这是你自己写的 如果要执行步骤2,可以执行以下操作

    首先,您需要计算每个维度的比例因子。基本上,这是每个维度的输出大小与原始输入si的比率