使用可变采样率平均周期性数据

时间:2017-04-13 13:43:36

标签: matlab average interpolation

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

plot

然而,我需要以某种方式平均嘈杂的圈数,以创建更准确的轨道单一地图。

我已经尝试在轨道的开头标记,以便识别新一圈的开始,然后平均每圈的每个对应点,但是由于每圈的数据点数量不同,这会导致更多错误。 / p>

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

有没有人知道某种方法可以将我的数据合并在一起以合并圈数?

1 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是定义轨道的开头,然后通过路径的标准化弧长参数化循环周围的每个遍历。然后,您可以使用此参数化沿轨道以特定间隔插入每条曲线并对结果取平均值。

% 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

  

注意:findpeakssmooth是工具箱函数,可能会被MATLAB文件交换中的函数替换。或者,如果您在汽车已经通过开头时知道,则可以完全删除findpeaks的使用情况。