Ubutntu下使用realsense d435i(三):使用yolo v5测量目标物中心点三维坐标
01 參考
本文下述使用參考的的工程均來自于下面的兩個github
- yolo v5參考的代碼:https://github.com/ultralytics/yolov5
- 本文參考的代碼(僅獲得深度):https://github.com/killnice/yolov5-D435i
- 上一個github代碼,csdn上的講解:realsense D455深度相機+YOLO V5結合實現目標檢測(一)
我的文件是在yolov5-D435i工程基礎上改的,yolov5-D435i是在yolov5工程基礎上改的。
02 分析
-
關于yolo部分
https://github.com/ultralytics/yolov5 這是一個比較經典的yolo v5的代碼,它提供了一些接口,在README.md中進行了介紹。
import torch # Model model = torch.hub.load('ultralytics/yolov5', 'yolov5s') # or yolov5m, yolov5l, yolov5x, custom# Images img = 'https://ultralytics.com/images/zidane.jpg' # or file, Path, PIL, OpenCV, numpy, list# Inference results = model(img)# Results results.print() # or .show(), .save(), .crop(), .pandas(), etc.
可以看到只要在自己寫的文件里創建model就可以調用這個結果了。
-
關于獲取三維坐標的部分
? https://github.com/killnice/yolov5-D435i里main_debug.py文件的深度獲取方法
—— 是在中心點附近取一些隨機點,然后深度排序取中值濾波。(這些被隨機選擇到的中心點,在圖中畫了藍色小圓圈標記這些點)
猜測這樣做是可以避免realsense獲取深度過程中,某點的忽然轉換失效,認為深度值為0,如果取周圍幾個點進行獲取深度,并中值濾波,將大大提高這個深度值在測量過程中的穩定性,避免了realsense忽然某幀某點的深度值為0的情況。? 我要獲得中心點的坐標,可以參考Ubutntu下使用realsense d435i(二):獲取某二維像素點的三維坐標
—— 修改get_mid_pos()函數,根據中心點的坐標以及中心點對應的深度獲取中心點的三維坐標。
但是這樣做也面臨一個問題,就是上面提到的,僅僅測量中心點的深度,當忽然這個深度值為0,他的三維坐標轉換就會出錯,如果把這個值設為機械臂的目標點,就會導致機械臂一瞬間點的位置出錯。
把realsense相機畫面的頻率降低會對這個現象改善一點,但還是存在,所以考慮可以參考上述深度值得解決辦法,也獲取周圍點,做一個中值濾波。
另外就是考慮相機還沒有標定,參考realsense d435相機標定,現在確實照墻壁時深度圖像有很多“黑洞”,這有可能也是忽然深度值為0的原因。? 未來要修改的地方
—— ① 把【像素x,像素y,深度值z】進行一個數據結構的保存(是選擇元祖、數組還是什么結構還沒有想好)
② 利用隨機數獲取周邊的一些點,同樣獲得這些點的【像素x,像素y,深度值z】
③ 把所有點根據深度值z進行排序和中值濾波,選擇排序中間的那一個點,根據深度值以及與其對應的像素x,y,獲得該點的三維坐標,并以此為目標物的三維坐標。
-
關于文件結構部分
由于yolo的測試程序以及對外開放了接口,所以我們只需要在原來的YOLO v5中(https://github.com/ultralytics/yolov5),再創建一個my_realsense_detect.py程序(不需要替換原來的detect.py程序),就可以了。
也就是說,把my_realsense_detect.py程序放到最開始提到的2個github程序中都可以運行。如果想放到其他的yolo程序,需要看看他具體提到的模型接口,結果接口都是什么。
03 代碼
首先我下載了https://github.com/killnice/yolov5-D435i。
我的文件是在yolov5-D435i工程基礎上改的,yolov5-D435i是在yolov5工程基礎上改的。
git clone https://github.com/killnice/yolov5-D435i.git realsense435_yolocd realsense435_yoloopen_anacondatorchpip install -r requirements.txtpip install pyrealsense2python main_debug.py然后是在main_debug.py文件的基礎上進行了修改,并把它重命名為了my_realsense_detect.py
說明:
?
在yolov5-D435i工程中的main.py、main_debug.py和try.py都是可以刪除的,只要運行my_realsense_detect.py就可以
?
在yolov5工程中,只要把my_realsense_detect.py文件復制進去就也可以運行啦
接下來是我的代碼,只放上了核心部分,具體可以根據yolov5-D435i工程中的main_debug.py文件進行修改。
def get_mid_pos(aligned_depth_frame,box):mid_pixel = [(box[0] + box[2])//2, (box[1] + box[3])//2] #確定索引深度的中心像素位置# 注意mid_pixel是float,但是get_distance()的參數需要是int[x, y] = [int(mid_pixel[0]), int(mid_pixel[1])]depth_intrin = aligned_depth_frame.profile.as_video_stream_profile().intrinsics # 獲取相機深度參數dis = aligned_depth_frame.get_distance(x, y) # 獲取該像素點對應的深度# print ('depth: ',dis) # 深度單位是mcamera_coordinate = rs.rs2_deproject_pixel_to_point(depth_intrin, [x, y], dis)# print ('camera_coordinate: ',camera_coordinate)return camera_coordinatedef dectshow(org_img, boxs,aligned_depth_frame):img = org_img.copy()for box in boxs:cv2.rectangle(img, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 255, 0), 2)point_3d = dist = get_mid_pos(aligned_depth_frame,box)[x, y, z] = point_3d# cv.putText 圖片,添加的文字,左上角坐標,字體,字體大小,顏色,字體粗細cv2.putText(img, box[-1] + ' (' + str(x)[:4] + ',' + str(y)[:4] + ',' + str(z)[:4] + ')',(int(box[0]), int(box[1])), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 1)cv2.imshow('dect_img', img)這個程序需要說明的是像素坐標的中點是float形式,而get_distance(x, y)函數的參數是int形式,需要進行強制轉換。
04 待解決的問題
- 中值濾波或標定等
總結
以上是生活随笔為你收集整理的Ubutntu下使用realsense d435i(三):使用yolo v5测量目标物中心点三维坐标的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue中登录验证成功后保存token,并
- 下一篇: 浅析互联网产品分类