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-1legend_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_numdistance{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_numA(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 == 0person(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_numkind_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_numfprintf("第 %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 - 1for j = i + 1 : nif A(i) > A(j)temp = A(j);A(j) = A(i);A(i) = temp;endendendsecondMin = A(2);idx = find(B == secondMin); end5 . 程序使用說明
運行程序
??打開person_trace_classification.m文件,使用MATLAB運行即可。
- 輸入需要繪制的軌跡數n。
- 在窗口用鼠標一一點出用戶的軌跡,回車結束。
- 控制臺打印輸入分類結果。
- 可以調整的參數
??MAX_DISTENCE,初始值為0.08,用戶可以根據自己繪制的軌跡圖像分類結果進行適當的調整。如將MAX_DISTENCE調大,則會將軌跡距離離得遠一點也可分為同一類;調小則相反。
6 . 運行流程及測試結果
1 . 點擊MATLAB運行按鈕,提示輸入需要繪制軌跡人數。
2 . 輸入你想要繪制軌跡的人數并回車,會彈出一個窗口用于畫軌跡
3 . 用鼠標一一點出軌跡,回車結束。
4 . 程序會繪畫出用戶的軌跡,并在控制臺打印輸出分類結果。
可以看出,分類效果還是挺不錯的!
總結
以上是生活随笔為你收集整理的MATLAB 实现轨迹分类(路径、曲线分类)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “2020年嵌入式软件秋招经验和对嵌入式
- 下一篇: 玉米生吃好还是熟吃好 各种情况分析