MATLAB - 三维数组插值
MATLAB - 3D 体积数据插值
Section titled “MATLAB - 3D 体积数据插值”三维 (3D) 插值是在给定一组排列在网格上的已知数据点的情况下,估算 3D 空间中任意点的值的过程。这项技术在许多科学和工程领域中都至关重要,例如医学成像(例如,对 MRI 扫描进行升采样)、计算流体力学 (CFD) 和地球物理数据分析。它允许您创建更平滑的可视化效果、提高数据分辨率或查询未明确测量的位置的值。
interp3 函数
Section titled “interp3 函数”MATLAB 用于此任务的主要工具是 interp3 函数。
Vq = interp3(X, Y, Z, V, Xq, Yq, Zq)Vq = interp3(V, Xq, Yq, Zq)Vq = interp3(V, k)Vq = interp3(___, method)Vq = interp3(___, method, extrapolation_val)Vq = interp3(X,Y,Z,V,Xq,Yq,Zq):这是最明确的形式。它对 3D 数组V(在网格坐标X,Y,Z定义)中的数据进行插值,以在新的查询坐标Xq,Yq,Zq处找到值Vq。Vq = interp3(V,Xq,Yq,Zq):一种更简单的形式,它假定一个默认采样网格(1:size(V,2)、1:size(V,1)、1:size(V,3))。Vq = interp3(V,k):将网格细化 2^k 倍。例如,k=1会在所有三个维度中,在每个现有采样点之间插入一个新的点。... , method):指定插值算法。常见的选择包括:-
'linear'(默认):快速且相当准确。一个很好的首选。
-
'nearest':最快,但会产生块状、不连续的输出。
-
'cubic':分段三次插值。产生比线性插值更平滑的结果,但计算量更大。
-
'spline':样条插值。通常产生最平滑的结果,但计算量也最大。
-
'makima':一种改进的 Akima 三次插值,可避免有时在'cubic'中出现的超调。
3D 插值示例
Section titled “3D 插值示例”让我们通过实际示例探索 interp3。请注意,我们将以文本形式描述图表,因为不使用图像。
示例 1:细化粗糙网格
Section titled “示例 1:细化粗糙网格”在这里,我们创建一个粗糙的 3D 数据集,并使用 interp3 生成一个更精细、更平滑的版本。
% 1. 定义粗糙网格和采样数据[X, Y, Z] = meshgrid(1:5, 1:5, 1:5);V = Z.^2 .* sqrt(X.^2 + Y.^2);
% 2. 定义更精细的查询网格[Xq, Yq, Zq] = meshgrid(1:0.25:5, 1:0.25:5, 1:0.25:5);
% 3. 使用 'cubic' 方法执行插值以获得平滑结果Vq = interp3(X, Y, Z, V, Xq, Yq, Zq, 'cubic');
% 4. 可视化结果figure;
% 绘制原始粗糙数据的切片subplot(1, 2, 1);slice(X, Y, Z, V, 3, 3, 3);shading flat; % 使用平面着色强调网格单元title('Original Coarse Data');xlabel('X'); ylabel('Y'); zlabel('Z');
% 绘制插值后的精细数据切片subplot(1, 2, 2);slice(Xq, Yq, Zq, Vq, 3, 3, 3);shading interp; % 使用插值着色以获得平滑外观title('Cubic Interpolated Data');xlabel('X'); ylabel('Y'); zlabel('Z');预期输出描述:此代码生成一个包含两个子图的图形。左侧的图,即“原始粗糙数据”,显示了数据的 3D 切片视图,由于它是在稀疏的 5x5x5 网格上渲染的,所以看起来呈块状。右侧的图,“三次插值数据”,显示了相同的切片,但更平滑、更详细,展示了插值到密集 21x21x21 网格上的效果。
示例 2:比较插值方法
Section titled “示例 2:比较插值方法”此示例可视化了在简单数据集上“线性”和“样条”插值之间的差异。
% 1. 创建一个带有单个“热点”的简单 3D 数据集V = zeros(5, 5, 5);V(3, 3, 3) = 1; % 在零值区域中有一个值为 1 的点
% 2. 使用 'linear' 方法进行插值Vq_linear = interp3(V, 2); % 将网格细化两倍
% 3. 使用 'spline' 方法进行插值Vq_spline = interp3(V, 2, 'spline');
% 4. 可视化结果figure;
% 线性插值结果subplot(1, 2, 1);slice(Vq_linear, 9, 9, 9); % 通过细化网格的中心切片title('Linear Interpolation');xlabel('X'); ylabel('Y'); zlabel('Z');
% 样条插值结果subplot(1, 2, 2);slice(Vq_spline, 9, 9, 9);title('Spline Interpolation');xlabel('X'); ylabel('Y'); zlabel('Z');预期输出描述:此代码生成两个子图。左侧的“线性插值”图显示了一个金字塔状的形状,其中单个热点的影响呈线性递减。右侧的“样条插值”图显示了一个更平滑的钟形分布,说明了样条如何从热点创建更连续和流畅的过渡。
最佳实践和注意事项
Section titled “最佳实践和注意事项”- 方法选择:首先使用
'linear'以获得速度和质量的良好平衡。当视觉平滑度至关重要时,使用'cubic'、'makima'或'spline'。仅当您需要保留原始数据值并且不希望创建任何新值时,才使用'nearest'。 - 性能:对大型 3D 数组进行插值计算成本很高。如果性能是问题,请考虑仅对数据的一个子集进行插值,或使用较低分辨率的查询网格。
- 外推:当查询点
(Xq,Yq,Zq)位于原始网格(X,Y,Z)边界之外时,请务必小心。interp3默认情况下会为这些点返回NaN(非数字)。您可以提供一个可选的第五个参数,为外推点指定一个常数值,例如interp3(..., 'linear', 0),以便对网格外的点返回 0。