前言
接續先前的 ROS 系列文章,本篇文章將會分享AMR ROS2光達搬運機器人在AI上的延伸應用,文章內容共有兩段:
第一段是了解如何應用獲得的深度影像,使用StereoLabs ZED 2i深度影像攝影機,從深度影像中取得畫面中心與相機的實際距離
第二段則是將深度影像的應用與AI影像辨識融合,結合上一篇中Jetson Inference ROS2套件detectnet的物件偵測功能,測量偵測到的物件與相機之間的距離
如果還沒有閱讀過前兩篇關於AI影像應用的文章,可以先往回閱讀之前的文章,會更容易了解這次所分享的內容:
AMR ROS2光達搬運機器人-分段路徑規劃與即時影像串流-使用NVIDIA Orin Nano
AMR ROS2光達搬運機器人-AI即時影像推論Jetson Inference-使用NVIDIA Orin Nano
攝影/撰寫 | 楊子賢 | 材料表 |
|
時間 | 3小時 | ||
難度 | 3(滿分5) |
本文
軟硬體背景
- NVIDIA Jetson Orin Nano
- StereoLabs ZED 2i
- Jetpack 5.1.1
- L4T 35.3.1
- Ubuntu 20.04 LTS
利用ZED深度影像攝影機取得畫面中心的距離
作為深度影像攝影機,StereoLabs ZED 2i理所當然的可以取得影像的深度,官方也有準備了範例,可以取得影像中心與攝影機的實際距離。在Orin Nano上使用ZED 2i攝影機的方法可以參考之前的文章,內容有提到如何建立並執行ZED攝影機的Docker容器:
首先要建立一個ZED攝影機的Docker容器
在Docker容器中,開啟ZED攝影機ROS2套件與Rviz
接著開啟另外一個終端機,連接到剛才的ZED攝影機Docker容器,並載入ROS2設定檔,才能夠執行下方的範例程式
執行深度距離範例,接著在終端機中就會輸出現在畫面中央與攝影機的距離
下方是範例中使用的程式碼,這邊有特別註記需要使用正確的服務品質設定(QoS, Quality of Service)才能接收到從ZED套件傳過來的訊息,這邊建立了一個名為depth_qos
的服務品質設定,它會盡可能地取得攝影機發布的訊息,並且只會接收新取得的資料。
利用準備好的設定建立一個訂閱者,訂閱來自ZED ROS2套件,名為depth
的深度影像訊息,這樣就完成範例程式中關於訂閱的初始設定
關於服務品質的設定與相容性請參考ROS2官方文件
接著要設定訂閱的回呼函式,每當收到訊息後,系統就會呼叫一次這個函式,處理接收到的訊息。為了讀取深度影像的內容,首先要將接收到的影像訊息內容轉為指標(Pointer),這樣就能用影像上的位置,推斷需要的數值在記憶體的所在位置。接著再使用訊息中影像的長寬,找出影像的中心位置,取出記憶體中對應位置的數值,就得到畫面中央與攝影機的距離。
結合影像辨識與深度影像取得物體的距離
有了從深度影像取得距離的方法後,就可以搭配上一篇文章中使用到的Jetson Inference ROS2影像辨識套件,先使用物件偵測來取得物體的位置後,再透過深度影像取得物體與攝影機的距離\
在終端機中開啟ZED深度攝影機的容器,並執行ZED ROS2套件
在另外一個終端機開啟Jetson Inference的容器,並執行Jetson Inference ROS2套件
再使用一個終端機開啟AMR Docker容器,執行detect_depth套件與RQT,等待程式啟動完成,在RQT的ImageView畫面中選擇 “/detectnet/person_depth”,就可以看到偵測到的物體距離
STEP1:初始設定
執行後程式所做的第一步是進行初始設定,總共會訂閱三個主題訊息,分別是來自ZED攝影機ROS2套件的深度影像depth_registered、來自Jetson Inference ROS2套件物件偵測程式detectnet的物件資訊detections,以及偵測結果的影像overlay,並發布一個包含物體距離的影像:名為person_depth的影像訊息
這邊使用了message_filter套件當中的訊息同步Approximate Synchronizer,只要設定好訂閱者與接收的時間範圍,它可以把時間相近的訊息整合在一個回呼函式中,以便處理來自不同訊息中的資料
STEP2:轉換影像訊息內容
第二步是在接收到訊息後呼叫的回呼函式當中,跟前面的範例程式相同,將接收到的深度影像訊息內容轉為指標,並保存影像的寬度,後續計算物體在影像上的位置時會使用到。還有使用cv_bridge套件將偵測結果影像訊息轉為容易修改的OpenCV格式,方便之後加上計算出來的距離數值
STEP3:計算物體位置
第三步一樣是在回呼函式當中,從物件偵測訊息中取出物體在影像上的中心座標,利用前面保存的畫面寬度,計算物體在畫面裡的位置,取出記憶體中對應的深度數值。為了避免同時有多個物體時,畫面會被大量的數字覆蓋,這邊把深度數值的精度調整到小數點後兩位,利用OpenCV繪製在偵測結果影像上。如果有不只一個物體被偵測到,就重複執行這一步,直到所有物體都處理完成,最後再用cv_bridge套件把OpenCV格式的結果影像轉換成ROS2影像訊息並發布
使用Rviz或是RQT訂閱上面發送的person_depth影像訊息就可以看到帶有距離數值的結果影像,圖中數字單位為公尺。
以上是ROS2搬運機器人結合專業景深攝影機的深度影像應用,後續會繼續分享ROS2上的各種應用,敬請期待喔!
〈AMR ROS2光達搬運機器人- AI物體距離偵測-使用NVIDIA Orin Nano〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。