Matlab中的三维(3D)矩阵插值 [英] Three dimensional (3D) matrix interpolation in Matlab

查看:348
本文介绍了Matlab中的三维(3D)矩阵插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a 3D matrix in Matlab of certain size, however I would need to interpolate it to obtain matrix of larger size.

size(M)
ans= 
  50   108    86

我需要对该矩阵进行插值并最终获得大小为100x213x140的矩阵.关于如何使用interp3进行操作的任何想法?这有可能吗?

I need that matrix to be interpolated and finally obtain a matrix of size 100x213x140. Any ideas of how to do it using interp3? Is this possible at all?

我尝试过

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似乎很喜欢,但是发生了两件事:

Matlab seems to like it, however two things happen:

  1. size(Vq) ans= 213 100 140
  2. 我可以在Vq
  3. 中看到NaN
  1. size(Vq) ans= 213 100 140
  2. I can see NaN values in Vq

背后的原因是因为我需要比较以不同频率采样的两个矩阵.因此,我可以对M进行插值以获得大小为100x213x140的矩阵,也可以将其他大小为100x213x140的矩阵M2的大小减小"到"50x108x86".我认为前者应该更轻松,更安全...

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. I thought the former should be easier and safer...

推荐答案

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

You almost have it right. You need to define 3D Grid of co-ordinates. Creating single vectors is not the right way to do it. You can certainly use interp3 here. Try doing:

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

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

Note that I have swapped the row (100) and column (213) limits, as the first parameter progresses horizontally while the second parameter progresses vertically.

此外,通过以这种方式使用interp3,我们假设XYZ的范围在1:2131:1001:140之内.如果您提供的值超出这些限制,则将得到NaN.有两种方法可以避免这种情况:

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. Should you provide any values outside of these limits, you will get NaN. There are a couple of ways you can avoid this:

  1. 在末尾指定spline标志以允许样条外推
  2. 如果要调整大小(例如,要调整图像大小),则当前没有内置方法可以以此方式调整3D矩阵的大小.您必须自己编写.
  1. Specify the spline flag at the end to allow for spline extrapolation
  2. If you want to resize the matrix (like if you were to resize an image), then there currently is no built-in method that can resize a 3D matrix this way. You'll have to write this yourself.

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

If you want to do Step #2, you can do the following.

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

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.

此后,您将创建一个2D网格,其限制由输入矩阵的原始大小限制,但是此网格的大小将与输出矩阵的大小相同.比例因子在这里很有用,因为这可以有效地给我们网格中每个值都应该进行插值.我们将创建新的坐标,该坐标从1到每个维的输出大小,以1/scaleFactor为增量.例如,如果我们想加倍矩阵的大小,这是2的因数.如果我们的XY坐标从1变为3,则为1到3,原始网格将如下所示:

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. 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. 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:

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,您可以做任何您想做的事情,但是为了简单起见,只需复制最后一行和最后一列,如此:

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:

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轻松地做到这一点,稍后我将向您展示如何做到这一点.因此,基本算法是这样的:

This defines our grid of 2D columns for resizing. Now it's a matter of resize in 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. As such, the basic algorithm is this:

  • 确定所需输出矩阵的输出大小
  • 确定每个维度的比例因子
  • 按照上述步骤为每个维度创建一个插值访问值的2D网格
  • 对于矩阵中的每个2D切片,请使用interp2使用上述2D网格将每个切片调整为输出行和列的大小.
  • 之后,使用interp1permute调整第三维尺寸.
  • Determine the output size of the output matrix you want
  • Determine the scale factors in each dimension
  • Create a 2D grid of interpolated access values for each dimension following the procedure above
  • For each 2D slice in your matrix, use interp2 to resize each slice to the output rows and columns using the above 2D grid.
  • After, use interp1 and permute to resize the third dimension.

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

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将是您最终插入/调整大小的3D矩阵.在3D中进行插值的关键方法是permute方法.这样做是对于z的每个值,我们将生成一个二维值切片.这样,如果我们在z = 1有一个切片,而在z = 2有一个切片,如果我们想找到切片z = 1.5处的2D值网格是什么,这将生成一个2D切片,该切片使用信息创建这些插值在z = 1z = 2之间.我们先进行permute调用,然后再进行permute调用以撤消排列并恢复原始尺寸.


MFinal would be your final interpolated / resized 3D matrix. The key method to interpolate in 3D is the permute method. What this will do is that for each value of z, we will generate a 2D slice of values. 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. We do the first call of permute to do this, then another permute call to undo our permutation and get the original dimensions back.

这篇关于Matlab中的三维(3D)矩阵插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆