目標檢測(Object Detection)是計算機視覺領域的核心任務之一,它旨在識別圖像中的物體并確定其位置,在本期的文章中,我們用一個端到端的目標檢測AI應用為例子。介紹如何在QCS6490 Ubuntu系統上實現一個目標檢測應用開發,我們選擇Yolov8n模型作為目標檢測的模型,以攝像頭的實時預覽的視頻流為輸入,最終將檢測到結果會更新到視頻畫面幀并且顯示出來。對于這樣一個任務,涉及到幾個關鍵的流程:
- Yolov8n模型的轉換和量化
- 攝像頭視頻的拉取和解碼,結果的實時顯示
- Yolov8n模型的推理
本期的系列文章將會針對這3個步驟展開,在這個例子中,我們選擇C++作為開發語言,但是文章的重點更多是關注在整體的流程和操作部署,而避免陷入太多的代碼實現中
- Yolov8n模型的轉換及量化
YOLOv8n 是?YOLOv8 系列的一個變體,它是由?Ultralytics 開發的最新一代目標檢測模型,在精度和速度都有不錯的表現。
1.1前置環境要求
Ubuntu 20.04 x64 機器
QCS6490 開發板
- 在Ubuntu 20.04 x64上安裝 Qualcomm AI Engine Direct SDK
軟件包的安裝說明和下載地址可以在以下鏈接獲得
https://www.qualcomm.com/developer/software/qualcomm-ai-engine-direct-sdk
? ? ?2.QCS6490 開發板安裝的是Ubuntu 20.04 arch64的系統鏡像
1.2?導出onnx模型
下載Yolov8n的預訓練模型
https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8n.pt
使用下面的python腳本把模型轉換成onnx模型
from ultralytics import YOLOmodel = YOLO("yolov8n.pt") ?# load a pretrained model (recommended for training)
path = model.export(format="onnx") ?# export the model to ONNX format
print(path)
1.3?準備模型量化的數據
Qualcomm?AI Engine Direct SDK提供了工具能夠非常的完成模型的轉換和量化工作。但是在模型量化之前,需要準備2個實際輸入的測試數據
由于Yolov8n預訓練的權重文件輸入shape是 [1,640,640,3] NHWC的張量,所以我們也需要準備一些準備640x640大小的圖片,并且把圖片轉換成float類型的張量,參考下面的python代碼片段
Src是輸入圖片的路徑
Dst是輸出的目錄
def convert_img_to_raw(src, dst, size,resize_type):img=cv2.imread(src) ? cv2.imwrite(dst,img)input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)input_img = input_img / 255.0raw_np = input_img[np.newaxis, :, :, :].astype(np.float32)#img_filepath = os.path.abspath(dst)filename, ext = os.path.splitext(dst)raw_filename = filenameraw_filename += '.raw'raw_np.tofile(raw_filename)print("save raw file to:",raw_filename)return 0
例如 把輸入src 為 “/data/test01.jpg”?dst 路徑為 “/data/raw”?最后得到 ?/data//raw/test01.raw
創建文本yolov8n_raw_list.txt
內容為
/data/raw/test01.raw
???????1.4?把Yolov8n的onnx模型轉換為高通QNN格式
請確認步驟1.1中的環境已經安裝完成,執行模型轉換命令
參考文檔 Qualcomm Documentation
先使用qnn-onnx-converter工具把onnx模型轉換為量化并轉換為QNN的中間文件
$QNN_SDK_ROOT/bin/x86_64-linux-clang/qnn-onnx-converter \--input_network ./yolov8n.onnx \--input_list yolov8n_raw_list.txt \--output_path ./qnn/yolov8n_quant.cpp \--quantization_overrides act.encodings
act.encodings?是一個json格式的文本文件,內容如下
{"activation_encodings": {"/model.22/Sigmoid_output_0": [{"bitwidth": 16,"dtype": "int","is_symmetric": "False","max": 0.996093750000,"min": 0.0,"offset": 0,"scale": 0.00001519941634}],"output0":[{"bitwidth": 16,"dtype": "int","is_symmetric": "False","max": 643.878662109375,"min": 0.0,"offset": 0,"scale": 0.00982495860394255}]},"param_encodings": {}
}
???????1.5?編譯QNN生成的代碼
使用 qnn-model-lib-generator ?工具編譯QNN生成的cpp代碼
$QNN_SDK_ROOT/bin/x86_64-linux-clang/qnn-model-lib-generator ?-c ./qnn/yolov8n_quant.cpp ?-b ./qnn/yolov8n_quant.bin \-o ./qnn_libs -t aarch64-ubuntu-gcc9.4
最后在./qnn_libs/aarch64-ubuntu-gcc9.4文件夾下面得到libyolov8n_quant.so?文件到這一步我們完成了把Yolov8的模型文件轉換成QNN格式的libyolov8n_quant.so文件
???????1.6?拷貝so文件到QCS6490的開發板
我們把1.5編譯QNN生成的代碼?中生成的libyolov8n_quant.so文件拷貝的QCS6490的開發板上,同樣的QCS6490也需要安裝Qualcomm?AI Engine Direct SDK?
接下來我們做個圖預編譯的動作,把libyolov8n_quant.so序列化 為yolov8n_quant.bin文件
$QNN_SDK_ROOT/bin/aarch64-ubuntu-gcc9.4/qnn-context-binary-generator \
--model ./libyolov8n_quant.so \
--backend libQnnHtp.so ?--binary_file yolov8n_quant
最后得到yolov8n_quant.bin 整個模型轉換步驟完成
作者:Ricky Li