matlab - 以可变采样率平均周期性数据

标签 matlab average interpolation

我有一长串[x,y] 玩具车绕轨道运行 5-6 圈的坐标值。每圈的数据点数量不一致(每圈有 50-60 个 [x,y] 点)。在 Matlab 中绘制的数据是有意义的,它绘制了汽车在赛道上移动的情况:

plot

但是,我需要以某种方式对嘈杂的圈数进行平均,以创建更准确的单一赛道 map 。

我尝试标记赛道的起点,以便识别新一圈的开始,然后对每圈的每个相应点进行平均,但是由于每圈的数据点数量不同,这会导致更多错误。

我考虑过对 [x,y] 数据进行排序,以将所有点连接到一圈中,但这不起作用,因为轨道是圆形的。

有谁知道如何以某种方式将我的数据平均起来以将圈数合并在一起?

最佳答案

实现此目的的一种方法是定义轨道的起点,然后通过路径的标准化弧长对循环周围的每次遍历进行参数化。然后,您可以使用此参数化沿轨道以特定间隔对每条曲线进行插值,并对结果进行平均。

% Assume that the first point is the start point (t = 0)
start_point = path(1,:);

% Compute the distance to this point for all data points
distances = sqrt(sum(bsxfun(@minus, path, start_point).^2, 2));

% Find the minima of this curve (these are all the times that the car passed the start)
% We apply some smoothing to get rid of necessary noise. Really depends on your data
[~, locs] = findpeaks(smooth(-distances, 20));

% Make sure we include the first and last point
locs = [1; locs; numel(distances)];

% Desired samples for each loop
nSamples = 1000;

% Pre-allocate the outputs
xpoints = zeros(numel(locs) - 1, nSamples);
ypoints = zeros(numel(locs) - 1, nSamples);

for k = 1:(numel(locs) - 1)
    % Get the coordinates recorded for this particular loop
    loop_points = path(locs(k):locs(k+1),:);

    % Compute the cumulative arc-length using these points
    arc_length = cumsum([0; sum(diff(loop_points, [], 1).^2, 2)]);

    % Normalize the arc_length between 0 and 1
    arc_length = arc_length ./ arc_length(end);

    % Interpolate along the curve
    xpoints(k,:) = interp1(arc_length, loop_points(:,1), linspace(0, 1, nSamples));
    ypoints(k,:) = interp1(arc_length, loop_points(:,2), linspace(0, 1, nSamples));
end

% Average all the x and y locations
X = mean(xpoints, 1);
Y = mean(ypoints, 1);

plot(X, Y)

我们可以通过一个完美的循环来测试这一点,并向每个电路添加一些噪声并每次更改样本数量

nLoops = 10;

x = [];
y = [];

for k = 1:nLoops
    nSamples = randi([50, 70]);

    t = linspace(0, 2*pi, nSamples + 1);
    t(end) = [];

    x = cat(1, x(:), cos(t(:)) + 0.1 * (rand(size(t(:))) - 0.5));
    y = cat(1, y(:), sin(t(:)) + 0.1 * (rand(size(t(:))) - 0.5));
end

path = [x(:), y(:)];

enter image description here

NOTE: findpeaks and smooth are toolbox functions that can likely be replaced with functions from the MATLAB File Exchange. Alternately, if you know when the car passes the beginning already, you can remove the usage of findpeaks altogether.

关于matlab - 以可变采样率平均周期性数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43393945/

相关文章:

Matlab:按升序计数出现次数而不是累积的命令?

jqplot - 如何在 jqPlot 的条形图上获得一条简单的平均值线

MySQL 查询平均日期范围

command-line - 通用 awk 脚本通过命令行参数计算任何字段的平均值

python - 使用 SciPy 二维插值器时出错

MATLAB 单元测试函数调用

matlab - 如何在神经网络Matlab中将训练数据制作为4D数组 - 输入数据的正确方法

numpy - 两个二维数组的线性插值

matlab - 在 GUI MATLAB 中为静态文本赋值

python - 从插值函数中检索值