Jetson Inference范例是NVIDIA 提供給Jetson系列的邊緣裝置進行視覺影像識別的范例,主要的特色在于這些范例都特別強調以NVIDIA Jetson系列邊緣裝置內的GPU進行運算,在實測上也的確發揮了很好的影像識別效果,尤其在對象偵測(Object Detection)所使用的Detectnet范例更有效率的辨識效能。
RealSense D435則是Intel推出的RealSense系列產品之一,這系列的產品主要是以輸出影像深度信息(測距)的應用為主,RealSense D435透過光學測距的方式進行深度信息的探測,在應用上有著不錯的探測效果。
影像對象偵測一直都是影像深度學習的重要應用之一,透過神經網絡對于對象(Object)的種類進行辨識進而確認對象在影像中的直角坐標位置,在辨識上僅能確認對象的影像方位,這樣的影像對象偵測由于缺少了對象與攝影機的相對距離,因此在更進一步的應用上便會受到一些局限,例如:透過影像信息控制機械手臂,自動夾取指定的物品、自駕車或無人飛行器精確的回避障礙物或跟蹤控制。
因此本文將著重在對象與攝影機的相對距離應用在影像對象偵測的實作教學上,希望能夠透過這樣的實作教學讓每個使用者可以進一步的針對影像對象偵測進行測量距離,這次采用的微電腦平臺是NVIDIA Jetson Nano 4GB嵌入式系統,與Intel的影像深度攝影機Realsense D435兩者進行整合,本文針對NVIDIA的GStreamer技術進行簡介,主要是因為NVIDIA的Jetson Inference相關應用,都是透過GStreamer進行影像數據的交換傳輸,透過GStreamer可以有效提升圖像處理的效能。
一、Jetson Inference應用程序操作環境的安裝與設定
Jetson Inference程序操作環境的設定主要是會完成三個環境更新安裝與設定,分別是:
1.Python程序的相依套件程序安裝(如:Pytroch等)
2.Python程序的編譯與路徑參數設定
3.影像識別相關預訓練神經模型的安裝
/有關Jetson Inference程序的安裝與設定,請參考之前的文章。--小編/
本文所采用的主要的是detectnet這個范例應用為主,因此若使用者對于安裝空間有所斟酌的話,請優先完成這部分的安裝,請注意,本文建議盡可能將detectnet所需要用到的預訓練神經網絡模型全部安裝,這樣可以避免未來在應用時產生補充安裝模型的問題。此外這里的安裝會需要從網絡下載大量程序與檔案,因此請務必確認網絡傳輸環境在長時間運作下,能夠正常傳輸。
Jetson Inference的范例程序運作,主要是透過CUDA連結GPU的方式進行Tensor-RT的運算,也由于是透過GPU進行運算,在操作影像識別的神經網絡運算時有著較佳的運作效能。透過GStreamer進行影像串流的處理,可以有效提升影像傳輸的效能,在Jetson Inference的神經網絡運算時,也都是以GStreamer的方式進行影像數據的傳遞。
透過上述這兩方面的技術的整合,對于影像對象偵測是有非常重要的貢獻,根據實測在進行detectnet程序運作的時候,整體約莫會有25FPS的操作效能,這歸功于CUDA有效連結了GPU進行運算產生的效益。
二、intel Realsense D435深度影像應用程序操作環境的安裝與設定
Realsense相關應用程序操作環境的安裝與設定主要是針對以下三個事項進行設定,分別是:
1.Python相依套件的安裝
2.Realsense應用程序的編譯與路徑設定
3.Realsense-viewer或Python程序的安裝
/有關Realsense程序的安裝與設定,請參考之前的文章進行安裝即可。--小編/
Realsense的影像信息其格式必須經過numpy套件程序的轉換處理才能呈現實時影像,這部分的介紹將會在后續的介紹當中,透過片段程序的進行重點說明,Realsense在運作的時候基本上會有兩種不同內容的影像輸出,一個是標準RGB的影像輸出,另一個具有深度信息的影像輸出,這兩個影像在應用時必須要注意「影像信息對齊」,這主要的原因在于兩種影像在擷取的時候可能會有兩種不同的分辨率的設定。在實際的硬件規格當中亦可以看出這兩種影像分辨率的極限的確有所不同。
Intel Realsense D435原廠網站資料
https://www.intelrealsense.com/depth-camera-d435/
三、系統架構圖
從上圖可知,Realsense D435要透過Numpy套件程序才能將影像信息轉換成OpenCV格式進行后續的圖像處理,如:繪邊界框、標注文字與實時影像顯示等,而要進行Jetson Inference的detectnet運算之前,亦必須先透過CUDA轉換數據將OpenCV格式轉換成GStreamer格式才能進行detectnet神經網絡運算,之后再將detectnet辨識后的結果,如:邊界框位置信息、對象種類名稱,加入至RGB影像訊息內容中,最后與深度影像信息進行對齊,如此便可以OpenCV進行整合后的影像呈現。
四、程序設計說明
<匯入相關套件>
1.JetsonInference 相關套件
主要有inference、jetson.utils
2.Realsense相關套件
主要是pyrealsense2
3.OpenCV相關套件
主要是cv2
4.Numpy數值運算相關套件
主要是numpy
#!/usr/bin/python3
#
#Copyright (c) 2021, Cavedu. All rights reserved.
#
importjetson.inference
importjetson.utils
importargparse
importsys
importos
importcv2
importre
importnumpy as np
importio
importtime
importjson
importrandom
importpyrealsense2 as rs1234567891011121314151617181920212223242526
<程序外部參數設定>
1.–network指定預訓練神經網絡模型
2.–threshold設定影像辨識閥值(多少以上才進行顯示)
3.–width 設定影像寬度
4.–height設定影像高度
# parsethe command line
parser =argparse.ArgumentParser(description="Locate objects in a live camerastream using an object detection DNN.",
formatter_class=argparse.RawTextHelpFormatter,epilog=jetson.inference.detectNet.Usage() +
jetson.utils.logUsage())
parser.add_argument("--network",type=str, default="ssd-mobilenet-v2",
help="pre-trained modelto load (see below for options)")
parser.add_argument("--threshold",type=float, default=0.5,
help="minimum detectionthreshold to use")
parser.add_argument("--width",type=int, default=640,
help="set width forimage")
parser.add_argument("--height",type=int, default=480,
help="set height forimage")
opt =parser.parse_known_args()[0]12345678910111213141516171819
設定jetson.inference的神經網絡運算為detectnet,并且透過opt.network的外部參數進行設定預訓練神經網絡模型。
# loadthe object detection network
net =jetson.inference.detectNet(opt.network, sys.argv, opt.threshold)123
設定Realsense套件的起始條件,并且啟動Realsense套件程序。
#Configure depth and color streams
pipeline= rs.pipeline()
config =rs.config()
config.enable_stream(rs.stream.depth,opt.width, opt.height, rs.format.z16, 30)
config.enable_stream(rs.stream.color,opt.width, opt.height, rs.format.bgr8, 30)
# Startstreaming
pipeline.start(config)12345678910
由于啟動本程序會進行大量運算,而使微電腦的核心產生高熱,因此透過本行程序啟動散熱風扇進行降溫。
os.system("sudosh -c 'echo 128 > /sys/devices/pwm-fan/target_pwm'")1
讀取Realsense D435影像內容并且透過Numpy將數據轉成OpenCV格式。
depth_image:深度影像信息
show_img:BGR影像信息
press_key= 0
while(press_key==0):
# Waitfor a coherent pair of frames: depth and color
frames = pipeline.wait_for_frames()
depth_frame = frames.get_depth_frame()
color_frame = frames.get_color_frame()
if not depth_frame or not color_frame:
continue
#Convert images to numpy arrays
depth_image =np.asanyarray(depth_frame.get_data())
show_img =np.asanyarray(color_frame.get_data())12345678910111213141516
透過CUDA進行OpenCV的BGR影像格式轉換,并且將影像格式調整適用于神經網絡運算的GStreamer格式(img)。
#convert to CUDA (cv2 images are numpy arrays, in BGR format)
bgr_img =jetson.utils.cudaFromNumpy(show_img, isBGR=True)
#convert from BGR -> RGB
img =jetson.utils.cudaAllocMapped(width=bgr_img.width,height=bgr_img.height,format='rgb8')
jetson.utils.cudaConvertColor(bgr_img,img)12345678910
將img影像信息傳入神經網絡進行運算,并將結果存在detections中。
# detectobjects in the image (with overlay)
detections = net.Detect(img)123
取得所有detections中所有已辨識出來的對象種類與位置信息。
box_XXXXX:邊界框坐標
score:辨識信心分數
label_name:對象種類名稱
for numin range(len(detections)) :
score =round(detections[num].Confidence,2)
box_top=int(detections[num].Top)
box_left=int(detections[num].Left)
box_bottom=int(detections[num].Bottom)
box_right=int(detections[num].Right)
box_center=detections[num].Center
label_name =net.GetClassDesc(detections[num].ClassID)12345678
透過OpenCV進行每個被辨識出來的對象其邊界框繪制、中心準線繪制與標注辨識結果內容文字。
point_distance=0.0
for i inrange (10):
point_distance = point_distance +depth_frame.get_distance(int(box_center[0]),int(box_center[1]))
point_distance= np.round(point_distance / 10, 3)
distance_text= str(point_distance) + 'm'
cv2.rectangle(show_img,(box_left,box_top),(box_right,box_bottom),(255,0,0),2)
cv2.line(show_img,
(int(box_center[0])-10,int(box_center[1])),
(int(box_center[0]+10),int(box_center[1])),
(0, 255, 255), 3)
cv2.line(show_img,
(int(box_center[0]),int(box_center[1]-10)),
(int(box_center[0]),int(box_center[1]+10)),
(0, 255, 255), 3)
cv2.putText(show_img,
label_name + ' ' + distance_text,
(box_left+5,box_top+20),cv2.FONT_HERSHEY_SIMPLEX,0.4,
(0,255,255),1,cv2.LINE_AA)1234567891011121314151617181920212223
透過net.GetNetworkFPS擷取神經網絡辨識的FPS值,并且透過OpenCV在實時影像畫面中標注其FPS數值內容。
cv2.putText(show_img,
"{:.0f}FPS".format(net.GetNetworkFPS()),
(int(opt.width*0.8),int(opt.height*0.1)),
cv2.FONT_HERSHEY_SIMPLEX,1,
(0,255,255),2,cv2.LINE_AA)12345
透過OpenCV的resize函數進行顯示畫面的調整,并且進行實時影像的顯示。
display= cv2.resize(show_img,(int(opt.width*1.5),int(opt.height*1.5)))
cv2.imshow('Detecting...',display)
keyValue=cv2.waitKey(1)
ifkeyValue & 0xFF == ord('q'):
press_key=11234567
關閉實時影像畫面,并且結束Realsense的串流影像傳送。
# 關閉所有 OpenCV 窗口
cv2.destroyAllWindows()
pipeline.stop()1234
五、程序執行方式
1.可透過MobaXterm以SSH方式聯機進入JetsonNano操作系統操作終端機,或是直接以HDMI屏幕、USB鍵盤鼠標直接操作亦可。
2.操作本文測試程序之前,請務必要先將Jetson Inference (請參考連結)與Realsense(請參考鏈接),兩個相關程序安裝完成,缺一不可。
3.進入終端機指定文件夾中(本文為Realsense_Jetson_Inference)
cd ~
cdRealsense_Jetson_Inference12
4.請確定測試程序存于本文件夾中,并請執行以下指令(默認為ssd-mobilenet-v2模型):
python3detectnet_realsense.py1
執行結果如下:
5.或指定其他預訓練神經網絡模型,請執行以下指令(本文例為pednet模型):
python3detectnet_realsense.py --network=pednet
編輯:黃飛
?
評論
查看更多