環(huán)境配置
安裝依賴(lài)包
如果在當(dāng)前python環(huán)境下能利用pip install onnx輕松安裝onnx,直接配置YOLOv5的環(huán)境即可;如果環(huán)境安裝有一些限制,建議跑模型的python環(huán)境為3.10。
# 在指定路徑下創(chuàng)建虛擬環(huán)境,我的anaconda安裝在c盤(pán),但我想把環(huán)境放在d盤(pán),所以利用--prefix D:\Anaconda3\envs\yolov5指定路徑 conda create --prefix D:\Anaconda3\envs\yolov5 python=3.10 # 切換虛擬環(huán)境 conda activate D:\Anaconda3\envs\yolov5 # 安裝關(guān)鍵包ONNX pip install -i https://pypi.tuna.tsinghua.edu.cn/simple onnx # 安裝yolov5依賴(lài)的pytorch pip install "torch-1.11.0+cu113-cp310-cp310-win_amd64.whl" "torchaudio-0.11.0+cu113-cp310-cp310-win_amd64.whl" "torchvision-0.12.0+cu113-cp310-cp310-win_amd64.whl" -i https://pypi.tuna.tsinghua.edu.cn/simple # 安裝yolov5需要的包 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib>=3.2.2 numpy>=1.18.5 opencv-python>=4.1.1 Pillow>=7.1.2 PyYAML>=5.3.1 requests>=2.23.0 scipy>=1.4.1 tqdm>=4.64.0 tensorboard>=2.4.1 pandas>=1.1.4 seaborn>=0.11.0 ipython psutil thop>=0.1.1
運(yùn)行YOLOv5
下載文件,參照如下流程操作:
①解壓yolov5-master.zip;
②將zidane.jpg放到y(tǒng)olov5-master文件夾中;
③將yolov5s.pt放到y(tǒng)olov5-master/models文件夾中;
④進(jìn)入yolov5-master文件夾,輸入python .\detect.py --weights .\models\yolov5s.pt --source zidane.jpg,代碼會(huì)輸出檢測(cè)結(jié)果保存路徑(以我為例:Results saved to runs\detect\exp9)檢測(cè)結(jié)果如下所示。
PyTorch的pt模型文件轉(zhuǎn)onnx
注意:BPU的工具鏈沒(méi)有支持onnx的所有版本的算子,即當(dāng)前BPU支持onnx的opset版本為10和11。
# 錯(cuò)誤的轉(zhuǎn)換指令 python .\export.py --weights .\models\yolov5s.pt --include onnx # 正確的轉(zhuǎn)換指令 python .\export.py --weights .\models\yolov5s.pt --include onnx --opset 11
轉(zhuǎn)換后,控制臺(tái)會(huì)輸出一些log信息,轉(zhuǎn)換后的模型文件在.\models\yolov5s.pt。
export: data=D:\05 - \01 - x3\BPUCodes\yolov5\yolov5-master\data\coco128.yaml, weights=['.\\models\\yolov5s.pt'], imgsz=[640, 640], batch_size=1, device=cpu, half=False, inplace=False, train=False, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=12, verbose=False, workspace=4, nms=False, agnostic_nms=False, topk_per_class=100, topk_all=100, iou_thres=0.45, conf_thres=0.25, include=['onnx'] YOLOv5 2022-9-1 Python-3.10.4 torch-1.11.0+cu113 CPU Fusing layers... YOLOv5s summary: 213 layers, 7225885 parameters, 0 gradients PyTorch: starting from models\yolov5s.pt with output shape (1, 25200, 85) (14.1 MB) ONNX: starting export with onnx 1.12.0... ONNX: export success 3.6s, saved as models\yolov5s.onnx (28.0 MB) Export complete (4.2s) Results saved to D:\05 - \01 - x3\BPUCodes\yolov5\yolov5-master\models Detect: python detect.py --weights models\yolov5s.onnx Validate: python val.py --weights models\yolov5s.onnx PyTorch Hub: model = torch.hub.load('ultralytics/yolov5', 'custom', 'models\yolov5s.onnx') Visualize: https://netron.app
模型轉(zhuǎn)換
新建一個(gè)文件夾bpucodes(可根據(jù)喜好自行命名),把前面轉(zhuǎn)好的yolov5s.onnx放進(jìn)這個(gè)文件夾里,在docker中,進(jìn)入bpucodes文件夾,開(kāi)始我們的模型轉(zhuǎn)換。
(PS:模型轉(zhuǎn)換需在docker中轉(zhuǎn)換,怎么安裝docker,怎么進(jìn)入OE,怎么掛載硬盤(pán)等相關(guān)問(wèn)題可在系列一中進(jìn)行查看)
模型檢查
模型檢測(cè)的目的是檢測(cè)有沒(méi)有不支持的算子,輸入指令hb_mapper checker --model-type onnx --march bernoulli2 --model yolov5s.onnx,開(kāi)始檢查模型,顯示如下內(nèi)容表示模型檢查通過(guò)。這時(shí)可以發(fā)現(xiàn)網(wǎng)絡(luò)的后端部分存在一些層是運(yùn)行在CPU上的,這會(huì)導(dǎo)致耗時(shí)多一些。
準(zhǔn)備校準(zhǔn)數(shù)據(jù)
校準(zhǔn)數(shù)據(jù)的代碼參考系列一中的YOLOv3的校準(zhǔn)代碼,整體沒(méi)有太多改變,輸入prepare_calibration_data.py可以得到校準(zhǔn)數(shù)據(jù)。
# 修改輸入圖像大小為640x640 img = imequalresize(img, (640, 640)) # 指定輸出的校準(zhǔn)圖像根目錄 dst_root = '/data/horizon_x3/codes/yolov5/bpucodes/calibration_data
開(kāi)始轉(zhuǎn)換BPU模型
輸入命令hb_mapper makertbin --config convert_yolov5s.yaml --model-type onnx開(kāi)始轉(zhuǎn)換我們的模型。校準(zhǔn)過(guò)后會(huì)輸出每一層的量化損失,轉(zhuǎn)換成功后,得到model_output/yolov5s.bin,這個(gè)文件拿出來(lái),拷貝到旭日X3派上使用,它也是我們上板運(yùn)行所需要的模型文件。
上板運(yùn)行
文件準(zhǔn)備
下載百度云的文件,拷貝到旭日X3派開(kāi)發(fā)板中,其中yolov5s.bin就是我們轉(zhuǎn)換后的模型,coco_classes.names僅用在畫(huà)框的時(shí)候,如果用自己的數(shù)據(jù)集的話(huà),參考coco_classes.names創(chuàng)建個(gè)新的名字文件即可。
輸入sudo apt-get install libopencv-dev安裝opencv庫(kù),之后進(jìn)入代碼根目錄,輸入python3 setup.py build_ext --inplace,編譯后處理代碼,得到lib/pyyolotools.cpython-38-aarch64-linux-gnu.so文件。
運(yùn)行推理代碼
模型推理的代碼如下所示,其中yolotools.pypostprocess_yolov5為C++實(shí)現(xiàn)的后處理功能,推理代碼在我這里保存為inference_model_bpu.py。
import numpy as np import cv2 import os from hobot_dnn import pyeasy_dnn as dnn from bputools.format_convert import imequalresize, bgr2nv12_opencv # lib.pyyolotools為封裝的庫(kù) import lib.pyyolotools as yolotools def get_hw(pro): if pro.layout == "NCHW": return pro.shape[2], pro.shape[3] else: return pro.shape[1], pro.shape[2] def format_yolov5(frame): row, col, _ = frame.shape _max = max(col, row) result = np.zeros((_max, _max, 3), np.uint8) result[0:row, 0:col] = frame return result # img_path 圖像完整路徑 img_path = '20220904134315.jpg' # model_path 量化模型完整路徑 model_path = 'yolov5s.bin' # 類(lèi)別名文件 classes_name_path = 'coco_classes.names' # 設(shè)置參數(shù) thre_confidence = 0.4 thre_score = 0.25 thre_nms = 0.45 # 框顏色設(shè)置 colors = [(255, 255, 0), (0, 255, 0), (0, 255, 255), (255, 0, 0)] # 1. 加載模型,獲取所需輸出HW models = dnn.load(model_path) model_h, model_w = get_hw(models[0].inputs[0].properties) print(model_h, model_w) # 2 加載圖像,根據(jù)前面模型,轉(zhuǎn)換后的模型是以NV12作為輸入的 # 但在OE驗(yàn)證的時(shí)候,需要將圖像再由NV12轉(zhuǎn)為YUV444 imgOri = cv2.imread(img_path) inputImage = format_yolov5(imgOri) img = imequalresize(inputImage, (model_w, model_h)) nv12 = bgr2nv12_opencv(img) # 3 模型推理 t1 = cv2.getTickCount() outputs = models[0].forward(nv12) t2 = cv2.getTickCount() outputs = outputs[0].buffer # 25200x85x1 print('time consumption {0} ms'.format((t2-t1)*1000/cv2.getTickFrequency())) # 4 后處理 image_width, image_height, _ = inputImage.shape fx, fy = image_width / model_w, image_height / model_h t1 = cv2.getTickCount() class_ids, confidences, boxes = yolotools.pypostprocess_yolov5(outputs[0][:, :, 0], fx, fy, thre_confidence, thre_score, thre_nms) t2 = cv2.getTickCount() print('post consumption {0} ms'.format((t2-t1)*1000/cv2.getTickFrequency())) # 5 繪制檢測(cè)框 with open(classes_name_path, "r") as f: class_list = [cname.strip() for cname in f.readlines()] t1 = cv2.getTickCount() for (classid, confidence, box) in zip(class_ids, confidences, boxes): color = colors[int(classid) % len(colors)] cv2.rectangle(imgOri, box, color, 2) cv2.rectangle(imgOri, (box[0], box[1] - 20), (box[0] + box[2], box[1]), color, -1) cv2.putText(imgOri, class_list[classid], (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, .5, (0,0,0)) t2 = cv2.getTickCount() print('draw rect consumption {0} ms'.format((t2-t1)*1000/cv2.getTickFrequency())) cv2.imwrite('res.png', imgOri)
輸入sudo python3 inference_model_bpu.py,推理結(jié)果保存為res.png,相關(guān)結(jié)果如下所示,可以看出,后處理部分耗時(shí)為7ms,C++和Python混編有效提升了代碼的運(yùn)行速度。
利用Cython封裝后處理代碼
①寫(xiě)后處理的C++代碼
首先,創(chuàng)建頭文件yolotools.h,用來(lái)記錄函數(shù)聲明,方便其他代碼調(diào)用。因?yàn)镃ython調(diào)用時(shí),調(diào)用C++的一些類(lèi)并不方便,所以寫(xiě)成C語(yǔ)言接口更方便調(diào)用。后處理的函數(shù)名為postprocess_yolov5,創(chuàng)建yolov5postprocess.cpp來(lái)對(duì)后處理函數(shù)進(jìn)行實(shí)現(xiàn)。
②寫(xiě)Cython所需的Pyx文件
同級(jí)目錄下創(chuàng)建pyyolotools.pyx,切記文件名不要跟某個(gè)CPP重復(fù)了,因?yàn)閏ython會(huì)將pyyolotools.pyx轉(zhuǎn)為pyyolotools.cpp,如果有重復(fù)的話(huà)可能會(huì)導(dǎo)致文件被覆蓋掉。
③寫(xiě)編譯Pyx所需的python代碼
創(chuàng)建setup.py文件,將下面代碼放進(jìn)去,配置好opencv的頭文件目錄、庫(kù)目錄、以及所需的庫(kù)文件。在Extension中配置封裝的函數(shù)所依賴(lài)的文件,然后在控制臺(tái)輸入python3 setup.py build_ext --inplace即可。
本文轉(zhuǎn)自地平線(xiàn)開(kāi)發(fā)者社區(qū)
原作者:小璽璽
-
python
+關(guān)注
關(guān)注
56文章
4823瀏覽量
86160 -
BPU
+關(guān)注
關(guān)注
0文章
4瀏覽量
2049
發(fā)布評(píng)論請(qǐng)先 登錄
在K230上部署yolov5時(shí) 出現(xiàn)the array is too big的原因?
HarmonyOS5云服務(wù)技術(shù)分享--Serverless抽獎(jiǎng)模板部署
RV1126 yolov8訓(xùn)練部署教程

請(qǐng)問(wèn)如何在imx8mplus上部署和運(yùn)行YOLOv5訓(xùn)練的模型?
yolov5轉(zhuǎn)onnx在cubeAI進(jìn)行部署,部署失敗的原因?
【米爾RK3576開(kāi)發(fā)板評(píng)測(cè)】+項(xiàng)目名稱(chēng)YOLOV5目標(biāo)檢測(cè)
【ELF 2學(xué)習(xí)板試用】ELF2開(kāi)發(fā)板(飛凌嵌入式)部署yolov5s的自定義模型
【ELF 2學(xué)習(xí)板試用】ELF2開(kāi)發(fā)板(飛凌嵌入式)搭建深度學(xué)習(xí)環(huán)境部署(RKNN環(huán)境部署)
《手把手教你做星閃無(wú)人機(jī)》即將開(kāi)播,鎖定15日晚七點(diǎn)!

采用華為云 Flexus 云服務(wù)器 X 實(shí)例部署 YOLOv3 算法完成目標(biāo)檢測(cè)

在RK3568教學(xué)實(shí)驗(yàn)箱上實(shí)現(xiàn)基于YOLOV5的算法物體識(shí)別案例詳解
在樹(shù)莓派上部署YOLOv5進(jìn)行動(dòng)物目標(biāo)檢測(cè)的完整流程

YOLOv6在LabVIEW中的推理部署(含源碼)

評(píng)論