[英]Three dimensional (3D) matrix interpolation in Matlab
I have a 3D matrix in Matlab of certain size, however I would need to interpolate it to obtain matrix of larger size. 我在Matlab中有一个特定大小的3D矩阵,但是我需要对其进行插值以获得更大尺寸的矩阵。
size(M)
ans=
50 108 86
I need that matrix to be interpolated and finally obtain a matrix of size 100x213x140
. 我需要对该矩阵进行插值并最终获得大小为100x213x140
的矩阵。 Any ideas of how to do it using interp3
? 关于如何使用interp3
任何想法? Is this possible at all? 这有可能吗?
I've tried 我试过了
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);
If I use meshgrid
: 如果我使用meshgrid
:
[X,Y,Z] = meshgrid(1:100, 1:213, 1:140);
Vq =interp3(M,X,Y,Z);
Matlab seems to like it, however two things happen: Matlab似乎很喜欢它,但是发生了两件事:
size(Vq) ans= 213 100 140
NaN
values in Vq
我可以在Vq
看到NaN
值 The reason behind is because I need to compare two matrices sampled at different frequency. 背后的原因是因为我需要比较以不同频率采样的两个矩阵。 So, I could either interpolate M
to obtain a matrix of size 100x213x140
or "reduce" the size of my other matrix M2
of size 100x213x140
to 50x108x86
. 所以,我既可以插M
获得大小的矩阵100x213x140
或“减少”我的其他矩阵大小M2
的尺寸100x213x140
到50x108x86
。 I thought the former should be easier and safer... 我认为前者应该更容易,更安全。
You almost have it right. 您几乎是正确的。 You need to define 3D Grid of co-ordinates. 您需要定义坐标的3D网格 。 Creating single vectors is not the right way to do it. 创建单个向量不是正确的方法。 You can certainly use interp3
here. 您当然可以在这里使用interp3
。 Try doing: 尝试做:
[X,Y,Z] = meshgrid(1:213, 1:100, 1:140);
Vq = interp3(M, X, Y, Z);
Note that I have swapped the row (100) and column (213) limits, as the first parameter progresses horizontally while the second parameter progresses vertically. 请注意,我已经交换了行(100)和列(213)的限制,因为第一个参数是水平进行的,而第二个参数是垂直进行的。
Also, by using interp3
in this fashion, we are assuming that the limits of X
, Y
and Z
fall within 1:213
, 1:100
and 1:140
. 同样,通过以这种方式使用interp3
,我们假设X
, Y
和Z
的限制落在1:213
interp3
1:100
和1:140
。 Should you provide any values outside of these limits, you will get NaN
. 如果您提供超出这些限制的任何值,则将获得NaN
。 There are a couple of ways you can avoid this: 有两种方法可以避免这种情况:
spline
flag at the end to allow for spline extrapolation 在末尾指定spline
标志以允许样条线外推 If you want to do Step #2, you can do the following. 如果要执行步骤2,则可以执行以下操作。
First, you need to figure out the scale factors for each dimension. 首先,您需要找出每个维度的比例因子。 Basically this is the ratio of the output size of each dimension with the original input size. 基本上,这是每个尺寸的输出尺寸与原始输入尺寸的比率。
After this, you create a 2D grid that has its limits bounded by the original size of the input matrix, but the size of this grid will be of the size of the output matrix. 此后,您将创建一个2D网格,其限制由输入矩阵的原始大小限制,但是此网格的大小将与输出矩阵的大小相同。 The scale factor is useful here because this effectively gives us what each value in the grid should be to interpolate. 比例因子在这里很有用,因为这可以有效地给我们网格中每个值都应该进行插值。 We would create new co-ordinates that went from 1 to the output size of each dimension, in increments of 1/scaleFactor
. 我们将创建新的坐标,该坐标从1到每个维度的输出大小,以1/scaleFactor
为增量。 As an example, if we wanted to double the size of our matrix, this is a factor of 2. If we had X
and Y
co-ordinates that went from 1 to 3 and 1 to 3 respectively, the original grid would look like this: 例如,如果我们想将矩阵的大小加倍 ,这是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
To double this, this would simply be: 要加倍,这将是:
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
Note that this create an output grid of 5 x 5. To make this doubled as 6 x 6, you can do whatever you want, but for the sake of simplicity, just duplicate the last row and last column, and so: 请注意,这将创建一个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
This defines our grid of 2D columns for resizing. 这定义了我们的2D列网格以调整大小。 Now it's a matter of resize in 3D. 现在是3D尺寸调整的问题。 What we can do is interpolate in between the slices . 我们可以做的是在切片之间进行插值。 We can easily do this using permute
in MATLAB, and I'll show you how to do that later. 我们可以使用MATLAB中的permute
轻松地做到这一点,稍后我将向您展示如何做到这一点。 As such, the basic algorithm is this: 因此,基本算法是这样的:
interp2
to resize each slice to the output rows and columns using the above 2D grid. 对于矩阵中的每个2D切片,请使用interp2
使用上述2D网格将每个切片调整为输出行和列的大小。 interp1
and permute
to resize the third dimension. 之后,使用interp1
并permute
以调整第三维的大小。 Without further ado, here is the code to do this: 事不宜迟,下面是执行此操作的代码:
%// 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
would be your final interpolated / resized 3D matrix. MFinal
将是您最终插入/调整大小的3D矩阵。 The key method to interpolate in 3D is the permute
method. 在3D中进行插值的关键方法是permute
方法。 What this will do is that for each value of z
, we will generate a 2D slice of values. 这将为z
每个值生成一个二维的值切片。 As such, if we had a slice at z = 1
and one at z = 2
, if we wanted to find what the 2D grid of values was at slice z = 1.5
, this will generate a 2D slice that creates these interpolated values using information between z = 1
and z = 2
. 这样,如果我们在z = 1
处有一个切片,在z = 2
处有一个切片,如果我们想找到切片z = 1.5
处的二维值网格,则将生成一个二维切片,该切片使用信息创建这些插值在z = 1
和z = 2
。 We do the first call of permute
to do this, then another permute
call to undo our permutation and get the original dimensions back. 我们做的第一个电话permute
要做到这一点,那么另一个permute
呼吁取消我们的置换,并获得原始尺寸回来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.