基于ORB-SLAM2與YOLOv8剔除動態特征點(三種方法)

基于ORB-SLAM2與YOLOv8剔除動態特征點(三種方法)

寫上篇文章時測試過程比較亂,寫的時候有些地方有點失誤,所以重新寫了這篇
本文內容均在RGB-D環境下進行程序測試

本文涉及到的動態特征點剔除速度均是以https://cvg.cit.tum.de/data/datasets/rgbd-dataset/download#freiburg3_walking_xyz數據進行實驗

方法1:segment坐標點集合逐一排查剔除

利用YOLOv8的segment獲取動態對象(這里指人person)所在區域的坐標點集合segpoints,之后將提取的特征點的坐標逐一與segpoints中的所有坐標作判斷,將出現在segpoints中的特征點的坐標改為(-1,-1),然后在畸變校正時會將坐標為(-1,-1)的異常坐標剔除。但是segpoints中的數據量太大,完成一次剔除任務花費的時間太長(基本在40~50ms,這個與動態區域的大小即segpoints中的點數是有關的)。另外,特征點坐標為浮點型,而segpoints中的坐標為整型,其實沒必要非用 = 判斷,可以判斷特征點在獲取的動態目標區域坐標的周圍1(可以調整,我最終在程序中使用半徑為2)個像素就可以了,這已經很接近=了。

下面是部分代碼:

std::vector<cv::Point> segpoints;
for (auto& obj:objs_seg) {int idx = obj.label;if (idx == 0){cv::Mat locations;cv::findNonZero(obj.boxMask == 255, locations);for (int i = 0; i < locations.rows; ++i) {cv::Point segpoint = locations.at<cv::Point>(i);segpoint.x += obj.rect.x;segpoint.y += obj.rect.y;segpoints.push_back(segpoint);}}
}
// 動態特征點的判斷
for (int k=0; k<mvKeys.size(); ++k){const cv::KeyPoint& kp = mvKeys[k];bool isDynamic = false;for (int kk = 0; kk < segpoints.size(); ++kk) {if (kp.pt.x > segpoints[kk].x-3 && kp.pt.x < segpoints[kk].x+3 && kp.pt.y > segpoints[kk].y-3 && kp.pt.y < segpoints[kk].y+3) {mvKeys[k] = cv::KeyPoint(-1,-1,-1);isDynamic = true;break;}}vbInDynamic_mvKeys.push_back(isDynamic);
}

方法2:利用目標檢測框

利用YOLOv8進行目標檢測,將檢測到的目標分為兩類:動態對象和靜態對象。
這里僅將person設為動態對象。獲取動態對象及靜態對象的檢測框后判斷提取的特征點是否在動態對象檢測框內以及是否在靜態對象檢測框內。

1.特征點在動態對象檢測框內而不在靜態對象檢測框內,則滿足剔除條件,將其剔除;
2.其余情況皆不滿足剔除條件。

采用這種方法速度提升至0.02~0.03ms.

struct DyObject {cv::Rect_<float> rect;int              id = 0;
};std::vector<ORB_SLAM2::DyObject> detect_results;
for (auto& obj:objs_det)
{int class_id = 0;// id為0代表其為靜態對象int class_label = obj.label;if (class_label == 0){// 如果是人person則將其id改為1即動態對象class_id = 1;}cv::Rect_<float> bbox;bbox = obj.rect;ORB_SLAM2::DyObject detect_result;detect_result.rect = bbox;detect_result.id = class_id;detect_results.push_back(detect_result);
}
// 判斷特征點是否在動態檢測框內
bool Frame::isDynamic(const int& i,std::vector<DyObject>& detect_results){const cv::KeyPoint& kp = mvKeys[i];float kp_u  = kp.pt.x;float kp_v = kp.pt.y;bool is_dynamic = false;for(auto& result:detect_results){int idx = result.id;if (idx == 1){double left = result.rect.x;double top = result.rect.y;double right = result.rect.x + result.rect.width;double bottom = result.rect.y + result.rect.height;if(kp_u>left-2 && kp_u<right+2 && kp_v>top-2 && kp_v<bottom-2){// 如果特征點在動態目標檢測框內is_dynamic = true;}}}return is_dynamic;
}// 判斷特征點是否在靜態檢測框內
bool Frame::isStatic(const int& i,std::vector<DyObject>& detect_results){const cv::KeyPoint& kp = mvKeys[i];float kp_u  = kp.pt.x;float kp_v = kp.pt.y;bool is_static = false;for(auto& result:detect_results){int idx = result.id;if (idx == 0){double left = result.rect.x;double top = result.rect.y;double right = result.rect.x + result.rect.width;double bottom = result.rect.y + result.rect.height;if(kp_u>left && kp_u<right && kp_v>top && kp_v<bottom){is_static = true;}}}return is_static;}

優化(方法3):目標檢測框+實例分割

針對方法1關于速度即處理數據量太大的問題,其實可以將方法1與方法2結合運用,先利用方法2進行判斷特征點是否在動態目標的檢測框內(不過不需要判斷是否在靜態目標的檢測框內了,方法2中如果在靜態目標檢測框內就保留該點而不會被剔除,這里舍棄此步驟也是寧缺毋濫的原則),如果判斷結果為真的話,則利用方法1將特征點與實例分割的Mask坐標進行判斷即可,這樣就可以節省很多時間了。

// 動態目標特征點的判斷
//先定義一種目標檢測的結果結構
struct DyObject {cv::Rect_<float> rect;std::vector<cv::Point> pts;int              id = 0;
};for (auto& obj:objs_seg) {int idx = obj.label;std::vector<cv::Point> segpoints;cv::Mat locations;cv::findNonZero(obj.boxMask == 255, locations);for (int i = 0; i < locations.rows; ++i) {cv::Point segpoint = locations.at<cv::Point>(i);cv::Rect_<float> rect;segpoint.x += obj.rect.x;segpoint.y += obj.rect.y;segpoints.push_back(segpoint);}ORB_SLAM2::DyObject detect_result;detect_result.rect = obj.rect;detect_result.pts = segpoints;detect_result.id = idx;detect_results.push_back(detect_result);
}

速度控制在了25ms以內。

方案1可以被舍棄了,對于方法2與方法3,測試一下二者在精度上的差異,因為從上面的工作中可以看出方法2的速度很快,如果精度差異很小的話為了SLAM實時性還是采用方法2比較好。
TUM提供了SLAM軌跡精度評估工具:
evaluate_ate.py、evaluate_rpe.py、associate.py
具體內容:https://cvg.cit.tum.de/data/datasets/rgbd-dataset/tools
將上面三個代碼下載后就可以對TUM數據集的結果軌跡進行精度評估了。

首先是方法2僅利用目標檢測框的一個特征點剔除情況:紫色的點就是之后會被剔除的點。

然后是方法3的特征點剔除情況:

上面兩張圖片的對比可以看出方法2會將一些有用的特征點也標記為動態特征點,而方法3會更精確。關于圖片中紅色圓圈,是我做的紋理分析,目前還沒完全做好所以就先不講了。

我對ORB-SLAM2與我基于ORB-SLAM2andYOLOv8(方法2與方法3)在數據集rgbd_dataset_freiburg3_walking_xyz的結果軌跡進行了精度評估,結果如下:

精度評估
TUM-freiburg3_walking_xyzORB-SLAM2DWT-SLAM detDWT-SLAM seg
RPE0.5555830.0225210.018761
ATE0.4742760.0173880.014755

方法3利用目標檢測框+實例分割的方法的精度是最優的。

下面再測測https://cvg.cit.tum.de/data/datasets/rgbd-dataset/download#freiburg3_walking_rpy

精度評估
TUM-freiburg3_walking_rpyORB-SLAM2DWT-SLAM detDWT-SLAM seg
RPE0.9686050.0358530.035431
ATE0.7880890.0299420.028222

https://cvg.cit.tum.de/data/datasets/rgbd-dataset/download#freiburg3_sitting_halfsphere

精度評估
TUM-freiburg3_walking_halfphereORB-SLAM2DWT-SLAM detDWT-SLAM seg
RPE0.3579840.0452500.029718
ATE0.2940750.0363010.023612

從以上從三個數據集獲得的三組精度評估結果來看,方法3的精度最高,25ms的動態特征點處理速度也是可接受的(我的電腦算是比較舊了)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696579.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696579.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696579.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

系統學習Python——裝飾器:類裝飾器-[單例類:編寫替代方案]

分類目錄&#xff1a;《系統學習Python》總目錄 有趣的是&#xff0c;這里如果能使用nonlocal語句&#xff08;僅在Python3.X中可用&#xff09;來改變外層作用域名稱&#xff0c;我們在這里可以編寫一個自包含程度更高的解決方案一一一下面的替代方案為每個類使用了一個外層作…

編寫程序,實現shell功能——項目訓練——day08

c c今天做了一個實戰項目訓練&#xff0c;編寫一個程序&#xff0c;實現shell功能&#xff0c;我們稱之為minishell。 主要是利用Linux中IO接口實現&#xff0c;實現的功能有&#xff1a; 1.ls ls -a ls -l cd cp mv pwd c…

軟件License授權原理

軟件License授權原理 你知道License是如何防止別人破解的嗎&#xff1f;本文將介紹License的生成原理&#xff0c;理解了License的授權原理你不但可以防止別人破解你的License&#xff0c;你甚至可以研究別人的License找到它們的漏洞。喜歡本文的朋友建議收藏關注&#xff0c;…

【Linux】進程狀態

進程狀態 進程狀態的簡要介紹運行狀態進程排隊 阻塞狀態掛起狀態Linux中的進程狀態 進程狀態的簡要介紹 進程狀態指的是一個操作系統中正在運行的進程當前所處的狀態。根據不同的操作系統&#xff0c;進程狀態可能會有一些細微的差別&#xff0c;但最主要的是以下三種狀態 運行…

Java——方法的使用

目錄 一.方法的概念及使用 1 什么是方法(method) 2.方法定義 3 方法調用的執行過程 4 實參和形參的關系(重要) 5.沒有返回值的方法 二.方法重載 1.為什么需要方法重載 2.方法重載概念 3.方法簽名 三.遞歸 1.遞歸的概念 2.遞歸執行過程分析 3. 遞歸練習 一.方法的…

貓頭虎分享已解決Bug || 容器編排問題:OrchestrationFailure, ContainerManagementError

博主貓頭虎的技術世界 &#x1f31f; 歡迎來到貓頭虎的博客 — 探索技術的無限可能&#xff01; 專欄鏈接&#xff1a; &#x1f517; 精選專欄&#xff1a; 《面試題大全》 — 面試準備的寶典&#xff01;《IDEA開發秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鴻蒙》 …

代碼隨想錄算法訓練營第四十二天|122. 買賣股票的最佳時機 II

674. 最長連續遞增序列 public static int findLengthOfLCIS(int[] nums) {int[] dp new int[nums.length];dp[0] 1;for (int i 1; i < nums.length; i) {dfs(nums, dp, i);}Arrays.sort(dp);return dp[dp.length - 1];}public static void dfs(int[] nums, int[] dp, i…

【Python】【VS Code】VS Code中python.json和setting.json文件配置說明

目錄 1. python.json配置 2. setting.json配置 3. 解決中文亂碼 4. 實現效果 1. python.json配置 python.json 獲取步驟&#xff1a;文件 -> 首選項 -> 配置用戶代碼片段 -> python 此為VS Code的頭文件設置&#xff0c;復制以下內容到 python.json {"HEADER…

個人做抖店如何能夠快速起店?掌握好技巧是關鍵!建議收藏!

大家好&#xff0c;我是電商小布。 相信我們每個朋友在店鋪開通后&#xff0c;最關心的事情就是小店成功起店了。 那么個人做抖店想要快速起店&#xff0c;該怎么來進行操作呢&#xff1f; 接下來&#xff0c;小布重點給大家說三點&#xff1a; 首先來說一下小店的主體類型…

git常用命令記錄

1、第一次初始化 git init git add . git commit -m ‘first commit’ git remote add origin gitgithub.com:帳號名/倉庫名.git git pull origin master git push origin master # -f 強推 git clone gitgithub.com:git帳號名/倉庫名.git 2、工作基本操作 git checkout master…

dell r740服務器黃燈閃爍維修現場解決

1&#xff1a;首先看一下這款DELL非常主力的PowerEdge R740服務器長啥樣&#xff0c;不得不說就外觀來說自從IBM拋棄System X系列服務器后&#xff0c;也就戴爾這個外觀看的比較順眼。 圖一&#xff1a;是DELL R740前視圖&#xff08;這款是8盤機型&#xff09; 圖二&#xff…

QT 數據庫的增加操作和畫圖 Win

第一步、先配置CMakeLists.txt 在CMakeLists.txt中添加 find_package(Qt6 REQUIRED COMPONENTS Sql) find_package(Qt6 REQUIRED COMPONENTS Charts)target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Sql) target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Charts)避…

springboot集成JWT實現token權限認證

vuespringboot登錄與注冊功能的實現 注&#xff1a;對于JWT的學習&#xff0c;首先要完成注冊和登錄的功能&#xff0c;本篇博客是基于上述博客的進階學習&#xff0c;代碼頁也是在原有的基礎上進行擴展 ①在pom.xml添加依賴 <!-- JWT --> <dependency><grou…

Linux篇:Shell命令以及運行原理 和 權限

一. Shell命令及原理 Linux操作系統狹義上是Linux內核&#xff0c;廣義上是指Linux內核Linux外殼(Shell)和對應的配套程序 Linux外殼&#xff1a;Linux 外殼是用戶與內核之間的接口&#xff0c;用戶通過外殼與操作系統進行交互和操作。在 Linux 系統中&#xff0c;用戶可以選…

C語言——static的三大用法

被稱為面試愛考愛問題的它到底有何奧義 它難度不大并且非常常用&#xff0c;話不多說&#xff0c;直接開始 一、局部靜態變量 定義 在函數內部使用static修飾的變量被稱為局部靜態變量&#xff0c;與普通的局部變量不同&#xff0c;局部靜態變量在使用后不會被銷毀&#xff…

pycharm 遠程運行報錯 Failed to prepare environment

什么也沒動的情況下&#xff0c;遠程連接后運行是沒問題的&#xff0c;突然在運行時就運行不了了&#xff0c;解決方案 清理緩存&#xff1a; 有時候 PyCharm 的內部緩存可能出現問題&#xff0c;可以嘗試清除緩存&#xff08;File > Invalidate Caches / Restart&#xff0…

mysql優化指南之原理篇

之前碰到一個線上問題&#xff0c;在接手一個同事的項目后&#xff0c;因為工期比較趕&#xff0c;我還沒來得及了解業務背景和大致實現&#xff0c;只是了解了上線發布的順序和驗證方式就進行了上線&#xff0c;在上線進行金絲雀的時候系統還沒發生什么異常&#xff0c;于是我…

【面試題】談談MySQL的事務

事務是啥 MySQL的事務就是把多個sql語句操作打包在一起執行&#xff0c;要么全部執行&#xff0c;要么一個都別執行。這種操作稱為“原子性”&#xff0c;是事務最核心的特征。當某個sql操作出錯時&#xff0c;就會進行“回滾/rollback”操作&#xff0c;即把執行過的操作逆向…

MySQL數據庫進階第二篇(索引,SQL性能分析,使用規則)

文章目錄 一、索引概述二、索引結構三、結構 - B-Tree四、結構 - BTree五、結構 - Hash六、索引分類七、索引語法1.案例代碼 八、SQL性能分析1.查看SQl執行頻率2.慢查詢日志3.PROFILES詳情4.EXPLAIN執行計劃 九、 索引使用規則十、SQL 提示十一、覆蓋索引十二、前綴索引十三、單…

滾動加載react-infinite-scroll-component

react-infinite-scroll-component 當請求數據量過大時&#xff0c;接口返回數據時間會很長&#xff0c;數據回顯時間長&#xff0c;Dom 的渲染會有很大的性能壓力。 antd的List組件中有提到一個滾動加載的組件庫react-infinite-scroll-component 實現滾動加載 Antd&#xff1…