1.1
簡介
本文章將在《自訓練Pytorch模型使用 OpenVINO 優化并部署在英特爾開發套件》文章的基礎上進行擴展,將介紹如何使用 OpenVINO Python API 對 YOLOv5 模型進行優化以及部署,完成 YOLOv5 目標檢測任務。
本文 Python 程序的開發環境是 Ubuntu20.04 LTS + PyCharm,硬件平臺是英特爾開發套件愛克斯開發板 AIxBoard。
本文項目背景:針對 2023 第十一屆全國大學生光電設計競賽賽題 2 “迷宮尋寶”光電智能小車題目。基于該賽項寶藏樣式,我通過深度學習訓練出能分類四種不同顏色不同標記形狀骨牌的模型,骨牌樣式詳見圖 1.1。
圖1.1 四種骨牌類型
1.2
YOLOv5 以及目標檢測
YOLO (You Only Look Once) 是目標檢測模型,目標檢測是計算機視覺中一種重要的任務,目的是在一張圖片中找出特定的物體,同時要求識別物體的種類和位置。在此之前的文章中 Pytorch 模型是用于圖像分類,只要求識別畫面中物體的種類。具體的區別通過圖 1.2.1 直觀可知。
圖 1.2.1 圖像分類、目標定位、目標檢測
01
通過 labelImg 對圖像進行數據集構建
Labelimg 是一款數據標注軟件,支持輸出包括 yolo, PascalVOC 等格式標注數據,這里我們選擇 yolo 格式即可。
在環境中執行:
pip install labelimg -i https://mirror.baidu.com/pypi/simple
而后打開 labelimg 軟件,如圖 1.2.2
圖 1.2.2 labelImg 軟件界面
如圖所示,選擇好圖片數據目錄 (Open Dir) 和數據標注保存目錄 (Choose Save Dir),就可以對想要的物體進行人工的數據標注。
02
標注好后檢查保存目錄中的 label 文件,查看是否無誤,如圖 1.2.3
圖 1.2.3 標注好的文件
03
本次實驗共標注 2000 張圖片(單分類 500 張共 4 分類)具體訓練流程在 YOLOv5 Github 有較為詳細的教程,在此不作為重點講解。得到 YOLOv5 模型后通過 OpenVINO Model Optimization 轉化成 IR 模型,這樣無論從處理速度還是精度都能獲得一定程度的優化。
1.3
使用 OpenVINO Runtime 對 YOLOv5 模型進行推理
在這一章節里我們將在 Pycharm 中使用 OpenVINO Runtime 對我們訓練的 YOLOv5 模型進行優化推理。
整個推理流程大致可以分為:
推理核心初始化 → 對輸入圖進行預處理 → 輸入到推理引擎獲得結果 → 通過置信度/NMS(非極大值抑制)過濾得到結果 → 將結果通過 OpenCV API 進行可視化
1.3.1
導入功能包
import openvino.runtime as ov import cv2 import numpy as np import openvino.preprocess as op
本次我們導入四個功能包,分別是 OpenVINO Runtime & PreProcess 、Numpy 、OpenCV。與之前不同在于我們需要使用 OpenVINO 自帶的預處理 API 對我們的模型進行一個預先處理,使得模型能夠正常工作在 OpenVINO 的推理引擎下。
PreProcess API 介紹:
OpenVINO PreProcess 是 OpenVINO Python API 大家庭的一員,主要是提供了一個 OpenVINO Runtime 原生用于數據預處理的 API 函數庫,在不用 PreProcess 時,開發者需要用第三方庫例如 OpenCV 來對其進行預處理,但是 OpenCV 作為一個開源的、廣泛的功能庫,數據預處理只能加載到 CPU 去進行實現,這無疑是增加對 CPU 資源的開銷,并且之后需要將處理后數據再次返還到 iGPU 等計算設備進行推理。而 PreProcess 提供了一種方式,使得預處理也能直接集成到模型執行圖中去,整個模型工作流程都在 iGPU 上流轉,這樣無需依賴 CPU,能提高執行效率。
由于輸入數據的不同,我們需要預處理來將數據能夠正確的進行處理。例如改變精度、改變輸入顏色通道、輸入數據的 Layout 等等。
整體 PreProcess 的流程大概是:
創建 PPP(PrePostProcess) 對象 → 聲明輸入數據信息 → 指定 Layout →設置輸出張量信息 → 從 PPP 對象中構建 Model 并進行推理
可以明顯得知,PreProcess 的存在使得預處理變得非常簡單易懂,只需要在在轉換前查看模型的輸入輸出信息,再比對自己環境下的輸入數據,進行預處理改變即可。而且整個環境都可以在 iGPU 等計算設備上運行,減輕了 CPU 負擔,可以把更多寶貴的資源留在處理其他重要事情上。
1.3.2
模型載入
將模型進行載入:
def Init(): global core global model global compiled_model global infer_request #核心創建 core = ov.Core() #讀取用YOLOv5模型轉換而來的IR模型 model = core.read_model("best2.xml", "best2.bin") #運用PPP(PrePostProcessor)對模型進行預處理 Premodel = op.PrePostProcessor(model) Premodel.input().tensor().set_element_type(ov.Type.u8).set_layout(ov.Layout("NHWC")).set_color_format(op.ColorFormat.BGR) Premodel.input().preprocess().convert_element_type(ov.Type.f32).convert_color(op.ColorFormat.RGB).scale( [255., 255., 255.]) Premodel.input().model().set_layout(ov.Layout("NCHW")) Premodel.output(0).tensor().set_element_type(ov.Type.f32) model = Premodel.build() compiled_model = core.compile_model(model, "CPU") #加載模型,可用CPU or GPU infer_request = compiled_model.create_infer_request() #生成推理
1.3.3
圖像尺寸調整
由于輸入圖的尺寸不確定性,在此我們特意加入一個 Resize 環節,用來適應不同分辨率的圖像,但是若輸入圖像尺寸較為穩定,只需要求出其變換圖的長寬比例即可。
def resizeimg(image, new_shape): old_size = image.shape[:2] #記錄新形狀和原生圖像矩形形狀的比率 ratio = float(new_shape[-1] / max(old_size)) new_size = tuple([int(x * ratio) for x in old_size]) image = cv2.resize(image, (new_size[1], new_size[0])) delta_w = new_shape[1] - new_size[1] delta_h = new_shape[0] - new_size[0] color = [100, 100, 100] new_im = cv2.copyMakeBorder(image, 0, delta_h, 0, delta_w, cv2.BORDER_CONSTANT, value=color) #增廣操作 return new_im, delta_w, delta_h
1.3.4
推理過程以及結果展示
在上一節中我們把輸入圖像所要進行的預處理圖像進行了一個定義,在這一小節則是 OpenVINO Runtime 推理程序的核心。
#************************************# # 推理主程序 # def main(img,infer_request): push =[] img_re,dw,dh = resizeimg(img,(640,640)) #尺寸處理 input_tensor = np.expand_dims(img_re, 0) #獲得輸入張量 infer_request.infer({0: input_tensor}) #輸入到推理引擎 output = infer_request.get_output_tensor(0) #獲得推理結果 detections = output.data[0] #獲得檢測數據 boxes = [] class_ids = [] confidences = [] for prediction in detections: confidence = prediction[4].item() #獲取置信度 if confidence >= 0.6: #初步過濾,過濾掉絕大多數的無效數據 classes_scores = prediction[5:] _, _, _, max_indx = cv2.minMaxLoc(classes_scores) class_id = max_indx[1] if (classes_scores[class_id] > .25): confidences.append(confidence) class_ids.append(class_id) x, y, w, h = prediction[0].item(), prediction[1].item(), prediction[2].item(), prediction[3].item() #獲取有效信息 xmin = x - (w / 2) #由于NMSBoxes緣故,需要從中心點得到左上角點 ymin = y - (h / 2) box = np.array([xmin, ymin, w, h]) #記錄數據 boxes.append(box) indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.5) #NMS篩選 detections = [] for i in indexes: j = i.item() detections.append({"class_index": class_ids[j], "confidence": confidences[j], "box": boxes[j]}) #儲存獲取的目標名稱和框選位 for detection in detections: box = detection["box"] classId = detection["class_index"] confidence = detection["confidence"] if(confidence<0.88): #再次過濾 ? ? ? ? ? ?continue ? ? ? ?else : ? ? ? ? ? ?push.append(classId) ? ? ? ?rx = img.shape[1] / (img_re.shape[1] - dw) ? ? ? ?ry = img.shape[0] / (img_re.shape[0] - dh) ? ? ? ?img_re = cv2.rectangle(img_re, (int(box[0]), int(box[1])), (int(box[0] + box[2]), int(box[1] + box[3])), (0, 255, 0), 3) ? ? ? ?box[0] = rx * box[0] #恢復原尺寸box,如果尺寸不變可以忽略 ? ? ? ?box[1] = box[1] *ry ? ? ? ?box[2] = rx * box[2] ? ? ? ?box[3] = box[3] *ry ? ? ? ?xmax = box[0] + box[2] ? ? ? ?ymax = box[1] + box[3] ? ? ? ?img = cv2.rectangle(img, (int(box[0]), int(box[1])), (int(xmax), int(ymax)), (0, 255, 0), 3) #繪制物體框 ? ? ? ?img = cv2.rectangle(img, (int(box[0]), int(box[1]) - 20), (int(xmax), int(box[1])), (0, 255, 0), cv2.FILLED) #繪制目標名稱底色填充矩形 ? ? ? ?img = cv2.putText(img, str(label[classId])+' ?'+str(int(confidence*100))+'%', (int(box[0]), int(box[1]) - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0)) ?#繪制目標名稱 ? ?cv2.imshow("d", img_re) ? ?cv2.imshow('w',img) ? ?cv2.waitKey(0)
以上推理函數編寫已經完成。以下是運行主程序:
#********************主程序***********************# def MainToSolve(infer): img = cv2.imread("boundtest.jpg") #如果需要實時,只需要將輸入img變成從攝像機抓取的幀畫面 main(img,infer) #從這里開始,初始化以及推理 Init() MainToSolve(infer_request)
當我們運行該程序時,會得到如圖 1.3.1。
圖 1.3.1 圖像結果
如圖所示,YOLOv5 模型通過轉換成IR模型,再經過 PPP 預處理以及 Runtime 引擎,成功運行在 AlxBoard。整體上性能非常不錯。
1.4
模型應用場景簡述:
原先的 Pytorch 模型只完成了圖像分類的任務,本文通過 YOLOv5 訓練并運用 OpenVINO 技術來完成了目標檢測這一更高難度的任務,通過得到物塊的位置我們就能更好的給予小車底盤信息,用來精確對物塊進行任務(抓取或是推到)
搭載 AlxBoard 的四輪小車如圖 1.4.1。
圖 1.4.1 AlxBoard 智能小車
通過此小車,我們還能發揮想象去做更多的應用場景,通過 OpenVINO 賦能小車系統,我們還能實現例如空對地無圖導航等等更具有特色的應用場景。
1.5
結論
自訓練 YOLOv5 模型在通過 OpenVINO Model Optimizer 模型優化后用 OpenVINO PreProcess 先進行預處理,處理后用 OpenVINO Runtime 進行推理,推理過程簡單清晰。推理整個過程由于加入了 PPP(PrePostProcess) 的預處理技術,整個處理可以放在 iGPU 上運行,有效減少 CPU 的開銷。通過 OpenVINO 技術優化后的模型優勢明顯,加上 AlxBoard 開發者板,能讓我們迅速構建起智能小車來驗證系統。
OpenVINO 簡單易上手,提供了健全的文檔和 OpenVINO Notebooks 范例,幫助開發者專注在自身應用的實現和算法搭建。
-
英特爾
+關注
關注
61文章
10011瀏覽量
172363 -
模型
+關注
關注
1文章
3317瀏覽量
49237 -
開發套件
+關注
關注
2文章
158瀏覽量
24336 -
深度學習
+關注
關注
73文章
5516瀏覽量
121570
原文標題:自訓練 YOLOv5 模型使用 OpenVINO? 優化并部署在英特爾開發套件 | 開發者實戰
文章出處:【微信號:英特爾物聯網,微信公眾號:英特爾物聯網】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
基于C#和OpenVINO?在英特爾獨立顯卡上部署PP-TinyPose模型
怎樣使用PyTorch Hub去加載YOLOv5模型
英特爾BOOT Loader開發套件-高級嵌入式開發基礎
![<b class='flag-5'>英特爾</b>BOOT Loader<b class='flag-5'>開發套件</b>-高級嵌入式<b class='flag-5'>開發</b>基礎](https://file.elecfans.com/web2/M00/49/3A/pYYBAGKhtECAVXDQAAARR6orNtM545.jpg)
在英特爾獨立顯卡上部署YOLOv5 v7.0版實時實例分割模型
在C++中使用OpenVINO工具包部署YOLOv5模型
基于OpenVINO在英特爾開發套件上實現眼部追蹤
使用英特爾哪吒開發套件部署YOLOv5完成透明物體目標檢測
![使用<b class='flag-5'>英特爾</b>哪吒<b class='flag-5'>開發套件</b><b class='flag-5'>部署</b><b class='flag-5'>YOLOv5</b>完成透明物體目標檢測](https://file1.elecfans.com/web2/M00/0D/3E/wKgaomdEQQmAcfF4AAB6yHq2BWc795.png)
評論