MATLAB 实现轨迹分类(路径、曲线分类)

1 . 题目要求:对用户轨迹进行分类,相同或相近的轨迹归为一类

背景:多个人在操场上随意散步。从用户进入操场到离开操场记录下他每步踩下的坐标(x,y)
假设他共走了n步,把他经过的全部坐标按序记录下来,就是他的运动轨迹:(x1,y1) (x2,y2),…(xn,yn)
要求把全部M个人的轨迹分类,相同或相近的轨迹归为一类。

注意:每个人的步数可能不一样,步距也可能步一样,进入和离开操场的地点都是随意的。

输入:M个人轨迹;相近轨迹距离最大值;XXX参数,……
输出:若干个分类(每类包含的路径)
算法:常规算法,分类/聚类算法,……

例如:这样的运动轨迹图
在这里插入图片描述

2 . 轨迹分类思想

  首先,我们要获取用户的这些轨迹点,即每个用户都会对应一个轨迹点集(可以用二维数组,结构体等实现),将这些轨迹点连接成线,就可以绘制出如上的轨迹曲线。
  然后,我们要求每条轨迹曲线间的距离。在计算之前,我们需要先自己拟定一个计算两条轨迹曲线间距离的方法。自己是这样计算的,比如有两条曲线,曲线A 和 曲线B,我们计算曲线A和B间的距离,可以先通过计算曲线A上的一点a1,到曲线B上所有点的欧式距离最小的距离,作为曲线A上点a1到曲线B的距离。然后,同样按照这种方法,可以计算出曲线A上其余轨迹点a2, a3, … , an到曲线B的距离。最后,我们将这些距离的平均值作为曲线A到曲线B的距离。
​  通过以上方法,我们就可以求得所有曲线间的距离,并可以得到一个距离矩阵。接着我们就需要来分析这个距离矩阵,并加上认为设定的阈值,一起作为曲线分类的判别条件。
  比如:我们计算了曲线A到其余曲线的距离,然后找到了这些距离中的最小值,并将其与阈值进行比较,若比阈值大,则将曲线A自己单独归为一类;若比阈值小,则将曲线A与相距那条的曲线归为一类。通过以上过程,我们就可以成功的将这些轨迹曲线进行分类,并输出最终分类结果。

3 . 程序设计思想

在这里插入图片描述

4 . MATLAB代码实现

%% Homework of Advanced software development technology and tools 
% Creation         :    17-Oct-2017
% Last Reversion   :    21-Oct-2017
% Author           :    Lingyong Smile {smilelingyong@163.com}
% File Type        :    Matlab
% -------------------------------------------------------------------------
% Lingyong Smile @ 2017
% 
% 作业要求:
%     对用户轨迹进行分类,相同或相近的轨迹归为一类
% 背景:多个人在操场上随意散步。从用户进入操场到离开操场记录下他每步踩下的坐标(x,y)
% 假设他共走了n步,把他经过的全部坐标按序记录下来,就是他的运动轨迹:(x1,y1) (x2,y2),(xn,yn)
% 要求把全部M个人的轨迹分类,相同或相近的轨迹归为一类。
% 注意:每个人的步数可能不一样,步距也可能步一样,进入和离开操场的地点都是随意的。
% 输入:M个人轨迹;相近轨迹距离最大值;XXX参数,……
% 输出:若干个分类(每类包含的路径)
% 算法:常规算法,分类/聚类算法,……


%% Init
clc;
clear;
close all;

% 设置阈值
MAX_DISTENCE = 0.08;

%% 手动绘制每个用户的轨迹点并记录下来,然后画出运动轨迹(用直线依次连接每一点)
figure(1);
person_num = input('输入需要绘制轨迹人数:');
legend_list = cell(person_num, 1);          % 创建一个cell数组,用于存放每条轨迹的用户名
for i = 1 : person_num
    [person(i).x, person(i).y] = ginput;    % 记录每个用户的轨迹坐标
    person(i).length = length(person(i).x);
    person(i).kind = i;  % 初始化用户的种类
    person(i).flag = 0;  % 初始化用户的种类标记位
    plot(person(i).x, person(i).y); % 绘制用户轨迹曲线        
    axis([0, 1, 0, 1]);     % 设置坐标范围在 0-1  0-1
    legend_list{i} = num2str(i); % 记录每条轨迹的用户名     
    text(person(i).x(2), person(i).y(2), num2str(i));   % 为每条轨迹线标注,便于直接在线上区分
    text(0.82, 0.09, ['阈值为:',num2str(MAX_DISTENCE)]); % 在图上显示当前输出的阈值
    hold on;
end
legend(legend_list);  % 添加图例      
title('The original trajectory of the user on the playground');  % 添加标题
% save(['person_', num2str(person_num), '.mat']);  % 保存用户轨迹数据,用于测试时使用
hold off;


%% 求得距离矩阵,并进行相应的数据处理
distance = cell(1, person_num);  % 初始化距离cell数组,用于存放第i条曲线到 所有 曲线的欧式距离
dist_idx = 1;

% 求曲线间的最近距离关系
for i = 1 : person_num
    % 求曲线i到所有曲线的欧式距离
    for j = 1 : person_num
        distance{dist_idx} = pdist2([person(i).x, person(i).y], [person(j).x, person(j).y]);  % 求条曲线i上每一点,到曲线j上每一点距离
        distance_point_to_line_min{dist_idx} = min(distance{dist_idx}, [], 2);   % 求曲线i上每个点,到第j条曲线上所有点的最小值, 每一行取最小值
        person(i).distance_line_to_line_min{dist_idx} = sum(distance_point_to_line_min{dist_idx}) / length(person(i).x); % 计算曲线i到曲线j的距离最小值的平均值
        dist_idx = dist_idx + 1;             
    end   
    dist_idx = 1;
end

% 得到曲线间最近距离矩阵A
for i = 1 : person_num
    A(i, :) = person(i).distance_line_to_line_min;
end
A = cell2mat(A);   % 将cell型转化为矩阵类型

% 对距离数组进行分类
m = size(A, 1);
for i = 1 : m
    [min_dist, min_dist_idx] = findSecondMin(A(i, :));
    if(A(i, min_dist_idx) < MAX_DISTENCE)     
        if person(i).flag == 0
            person(i).kind = min_dist_idx;
            person(min_dist_idx).flag = 1;           
        end 
    end
%     fprintf("第 %d 条曲线属于 %d 类\n",i, person(i).kind);
end


%% 得到类别数组,并进行分类 (unique())
kind_array = zeros(person_num, 1);
for i = 1 : person_num
    kind_array(i) = person(i).kind;
end
[cluster, ia, kind_idx] = unique(kind_array);
% 其中 cluster 分的类别种类, kind_idx 当前属于第几类


%% 打印输出类别信息
fprintf("总共有 %d 类:\n", length(cluster));
for i = 1 : person_num
    fprintf("第 %d 条曲线属于 第 %d 类\n",i, kind_idx(i));
end

%% 函数功能: 找一维数组A中第二小的元素以及下标
% 输入: 
%       A: 一维数组
% 输入:
%       secondMin:第二小的数
%       idx      :第二小的数对应的下标
function [secondMin, idx] = findSecondMin(A)
    B = A;
    n = length(A);
    for i = 1 : n - 1
        for j = i + 1 : n
            if A(i) > A(j)
                temp = A(j);
                A(j) = A(i);
                A(i) = temp;
            end
        end
    end
    
    secondMin = A(2);
    idx = find(B == secondMin);
end

5 . 程序使用说明

运行程序

  打开person_trace_classification.m文件,使用MATLAB运行即可。

  • 输入需要绘制的轨迹数n。
  • 在窗口用鼠标一一点出用户的轨迹,回车结束。
  • 控制台打印输入分类结果。
  • 可以调整的参数
      MAX_DISTENCE,初始值为0.08,用户可以根据自己绘制的轨迹图像分类结果进行适当的调整。如将MAX_DISTENCE调大,则会将轨迹距离离得远一点也可分为同一类;调小则相反。

6 . 运行流程及测试结果

1 . 点击MATLAB运行按钮,提示输入需要绘制轨迹人数。
在这里插入图片描述
2 . 输入你想要绘制轨迹的人数并回车,会弹出一个窗口用于画轨迹
img在这里插入图片描述
3 . 用鼠标一一点出轨迹,回车结束。
4 . 程序会绘画出用户的轨迹,并在控制台打印输出分类结果。
在这里插入图片描述在这里插入图片描述
可以看出,分类效果还是挺不错的!

  • 20
    点赞
  • 146
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
MATLAB是一种很常用的数学软件,它提供了许多用于规划轨迹的算法。轨迹规划是指通过给定的起始点和目标点,计算出一条机器人路径,使机器人能够从起始点平滑地到达目标点。在MATLAB中,可以使用以下算法来实现轨迹规划: 1. 最短路径规划算法:使用Dijkstra算法或A*算法等最短路径算法来计算出从起始点到目标点的最短路径。这些算法通过考虑节点之间的距离和成本,找到连接起始点和目标点的最短路径。 2. 光滑路径规划算法:一旦找到最短路径,可以使用光滑路径算法来消除路径中的折线,使得路径更加平滑。其中一种常用的算法是B样条曲线插值算法,它通过将路径离散化为一系列点,并使用B样条曲线来拟合这些点,从而得到一条光滑的路径。 3. 动态路径规划算法:当机器人需要避开动态障碍物时,可以使用动态路径规划算法。这些算法通过利用传感器数据来检测障碍物,并根据障碍物的位置和速度来更新路径,以实现动态避障。 MATLAB还提供了一些特定领域的轨迹规划工具箱,如机器人操作系统(ROS)的路径规划工具箱和机器人工具箱。这些工具箱提供了更多专门针对机器人路径规划问题的算法和功能,可以更方便地进行路径规划和仿真实验。 总而言之,MATLAB提供了丰富的轨迹规划算法和工具,可用于解决各种路径规划问题。无论是最短路径规划、光滑路径规划还是动态路径规划,MATLAB都能提供相应的算法和工具,帮助用户快速、高效地解决轨迹规划问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值