MATLAB - 插值
MATLAB - 数据插值技术
Section titled “MATLAB - 数据插值技术”插值是一种估计已知数据点之间未知值的过程。它是数据分析、信号处理和计算机图形学中的基本工具,用于重采样、平滑和填充缺失数据等任务。MATLAB 提供了一套全面的函数,用于对一维、二维和三维数据集以及散乱数据执行插值。
本教程重点介绍现代推荐的函数:用于一维数据的 interp1,用于二维网格数据的 interp2,用于三维网格数据的 interp3,以及用于更高级、注重性能的工作流程的 griddedInterpolant / scatteredInterpolant。
使用 interp1 进行一维插值
Section titled “使用 interp1 进行一维插值”interp1 函数是一维插值的主要工具。给定一组采样点 (x, v),interp1 在一组新的查询点 xq 处找到值 vq。
vq = interp1(x, v, xq)vq = interp1(x, v, xq, method)vq = interp1(..., 'extrap')其中 method 可以是 'linear'(默认)、'nearest'、'next'、'previous'、'pchip'、'cubic'、'spline' 或 'makima'。方法的选择决定了已知数据点之间曲线的构建方式。
示例 1:基本线性插值和样条插值
Section titled “示例 1:基本线性插值和样条插值”% 1. 定义原始的粗略采样数据x = 0:pi/2:2*pi;v = sin(x);
% 2. 定义更精细网格的查询点xq = 0:pi/16:2*pi;
% 3. 执行插值vq_linear = interp1(x, v, xq, 'linear'); % 线性插值vq_spline = interp1(x, v, xq, 'spline'); % 更平滑的样条插值
% 4. 绘制结果以进行比较figure;plot(x, v, 'o', 'MarkerSize', 10); % 原始采样点hold on;plot(xq, vq_linear, '.-'); % 线性插值结果plot(xq, vq_spline, '--'); % 样条插值结果hold off;
title('1D Interpolation of sin(x)');xlabel('X');ylabel('Value');legend('Original Samples', 'Linear Interpolation', 'Spline Interpolation', 'Location', 'southwest');输出图表显示了原始的粗略采样点为大圆圈。带点的蓝线显示了线性插值的“连点成线”结果。橙色虚线显示了样条插值产生的更平滑的曲线,这通常提供了更具物理合理性的拟合效果。
二维和三维网格插值
Section titled “二维和三维网格插值”对于在规则网格上定义的数据(如图像或三维体),使用 interp2 和 interp3。其语法与 interp1 类似。
示例 2:使用 interp2 对二维网格进行插值
Section titled “示例 2:使用 interp2 对二维网格进行插值”% 1. 创建粗略的二维网格和数据[X, Y] = meshgrid(-3:1:3); % Coarse gridZ = peaks(X, Y); % Z-values from the 'peaks' function
% 2. 创建更精细的网格以进行查询[Xq, Yq] = meshgrid(-3:0.25:3); % Fine grid
% 3. 使用 'cubic' 方法执行二维插值Zq = interp2(X, Y, Z, Xq, Yq, 'cubic');
% 4. 可视化比较figure;subplot(1, 2, 1);surf(X, Y, Z);title('Original Coarse Surface');
subplot(1, 2, 2);surf(Xq, Yq, Zq);title('Interpolated Fine Surface');输出显示了两个子图。左图显示了基于原始粗略数据的块状曲面。右图显示了通过将值插值到更精细网格上创建的更平滑、更高分辨率的曲面。“三次”方法(cubic method)确保了所得曲面是平滑的。
散乱数据插值
Section titled “散乱数据插值”当数据点 (x, y, z) 不在规则网格上时,它们被称为散乱数据。此时使用 griddata 函数,或者为了更好的性能,使用 scatteredInterpolant 对象。
示例 3:使用 scatteredInterpolant 提高效率
Section titled “示例 3:使用 scatteredInterpolant 提高效率”scatteredInterpolant 对象在您需要多次查询同一散乱数据集时是理想的选择,因为它只执行一次代价高昂的初始三角剖分。
% 1. 生成随机散乱数据点x = rand(100, 1) * 4 - 2; % 在 [-2, 2] 范围内的 100 个随机点y = rand(100, 1) * 4 - 2;z = x .* exp(-x.^2 - y.^2);
% 2. 创建插值对象F = scatteredInterpolant(x, y, z, 'natural');
% 3. 定义一个规则网格以查询插值器[Xq, Yq] = meshgrid(-2:0.1:2);Zq = F(Xq, Yq); % 在网格上评估插值器
% 4. 绘制结果figure;surf(Xq, Yq, Zq); % 绘制插值曲面hold on;plot3(x, y, z, 'o', 'MarkerFaceColor', 'r', 'MarkerEdgeColor', 'k'); % 叠加原始点hold off;
title('Interpolating Scattered Data');legend('Interpolated Surface', 'Original Scattered Points', 'Location', 'northwest');生成的图表显示了一个由散乱数据构建的平滑曲面。原始的 100 个数据点以红色圆圈的形式叠加,展示了曲面如何穿过它们。
最佳实践和方法选择
Section titled “最佳实践和方法选择”- 线性插值(Linear): 快速简单。适用于密集采样数据或对速度有严格要求的情况。
- 样条/Pchip/Makima: 生成平滑曲线。
'pchip'和'makima'是很好的通用选择,因为它们避免了'spline'有时可能产生的过冲。 - 最近邻(Nearest): 适用于分类数据,或当您需要保留原始值而不创建新值时。
- 性能: 对于同一数据集的重复插值,使用
griddedInterpolant或scatteredInterpolant可以显著提高性能。