你几乎说对了。您需要定义坐标的3D 网格。创建单个向量不是正确的方法。你当然可以在这里使用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。有几种方法可以避免这种情况:
- 在末尾指定
spline 标志以允许样条外推
- 如果您想调整矩阵的大小(例如调整图像的大小),那么目前没有可以通过这种方式调整 3D 矩阵大小的内置方法。你必须自己写这个。
如果您想执行第 2 步,您可以执行以下操作。
首先,您需要计算出每个维度的比例因子。基本上这是每个维度的输出大小与原始输入大小的比值。
在此之后,您将创建一个 2D 网格,其限制为输入矩阵的原始大小,但该网格的大小将与输出矩阵的大小相同。比例因子在这里很有用,因为它有效地为我们提供了网格中每个值应该插值的内容。我们将创建从 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
这定义了我们用于调整大小的 2D 列网格。现在是在 3D 中调整大小的问题。我们可以做的是在切片之间进行插值。我们可以在 MATLAB 中使用permute 轻松做到这一点,稍后我将向您展示如何做到这一点。因此,基本算法是这样的:
- 确定所需输出矩阵的输出大小
- 确定每个维度的比例因子
- 按照上述过程为每个维度创建一个包含插值访问值的 2D 网格
- 对于矩阵中的每个二维切片,使用
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 矩阵。在 3D 中插值的关键方法是 permute 方法。这将做的是,对于z 的每个值,我们将生成一个二维值切片。因此,如果我们在z = 1 有一个切片,在z = 2 有一个切片,如果我们想找到切片z = 1.5 的二维值网格,这将生成一个二维切片,它使用信息创建这些插值在z = 1 和z = 2 之间。我们首先调用permute 来执行此操作,然后再调用permute 来撤消我们的排列并取回原始尺寸。