繁体   English   中英

Matlab中的三维(3D)矩阵插值

[英]Three dimensional (3D) matrix interpolation in 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 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似乎很喜欢它,但是发生了两件事:

  1. size(Vq) ans= 213 100 140
  2. 我可以在Vq看到NaN

背后的原因是因为我需要比较以不同频率采样的两个矩阵。 所以,我既可以插M获得大小的矩阵100x213x140或“减少”我的其他矩阵大小M2的尺寸100x213x14050x108x86 我认为前者应该更容易,更安全。

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

[X,Y,Z] = meshgrid(1:213, 1:100, 1:140);
Vq = interp3(M, X, Y, Z);

请注意,我已经交换了行(100)和列(213)的限制,因为第一个参数是水平进行的,而第二个参数是垂直进行的。

同样,通过以这种方式使用interp3 ,我们假设XYZ的限制落在1:213 interp3 1:1001:140 如果您提供超出这些限制的任何值,则将获得NaN 有两种方法可以避免这种情况:

  1. 在末尾指定spline标志以允许样条线外推
  2. 如果要调整矩阵的大小 (例如要调整图像的大小),则当前没有内置方法可以以此方式调整3D矩阵的大小。 您必须自己编写。

如果要执行步骤2,则可以执行以下操作。

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

此后,您将创建一个2D网格,其限制由输入矩阵的原始大小限制,但是此网格的大小将与输出矩阵的大小相同。 比例因子在这里很有用,因为这可以有效地给我们网格中每个值都应该进行插值。 我们将创建新的坐标,该坐标从1到每个维度的输出大小,以1/scaleFactor为增量。 例如,如果我们想将矩阵的大小加倍 ,这是2的倍数。如果我们的XY坐标分别从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

这定义了我们的2D列网格以调整大小。 现在是3D尺寸调整的问题。 我们可以做的是在切片之间进行插值。 我们可以使用MATLAB中的permute轻松地做到这一点,稍后我将向您展示如何做到这一点。 因此,基本算法是这样的:

  • 确定所需输出矩阵的输出大小
  • 确定每个维度的比例因子
  • 按照上述步骤为每个维度创建一个内插访问值的2D网格
  • 对于矩阵中的每个2D切片,请使用interp2使用上述2D网格将每个切片调整为输出行和列的大小。
  • 之后,使用interp1permute以调整第三维的大小。

事不宜迟,下面是执行此操作的代码:

%// 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矩阵。 在3D中进行插值的关键方法是permute方法。 这将为z每个值生成一个二维的值切片。 这样,如果我们在z = 1处有一个切片,在z = 2处有一个切片,如果我们想找到切片z = 1.5处的二维值网格,则将生成一个二维切片,该切片使用信息创建这些插值在z = 1z = 2 我们做的第一个电话permute要做到这一点,那么另一个permute呼吁取消我们的置换,并获得原始尺寸回来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM