檢測:從模型轉(zhuǎn)換到NMS后處理的完整教程)
用RKNPU2部署YOLOv5目標(biāo)檢測從模型轉(zhuǎn)換到NMS后處理的完整教程【免費(fèi)下載鏈接】rknpu2項(xiàng)目地址: https://gitcode.com/gh_mirrors/rk/rknpu2本文帶你用RKNPU2Rockchip NPU 工具鏈在 RK3562/RK3566/RK3588 開發(fā)板上部署YOLOv5 目標(biāo)檢測模型從 ONNX 轉(zhuǎn)換 RKNN 模型、RKNN 推理主流程到 NMS 后處理參數(shù)調(diào)優(yōu)一份完整教程帶你快速跑通端側(cè) AI 檢測。上圖為 Demo 自帶的測試圖片examples/rknn_yolov5_demo/model/bus.jpg運(yùn)行檢測后會(huì)在原圖上畫出目標(biāo)框與置信度。一、RKNPU2 是什么為什么用它做目標(biāo)檢測RKNPU2是 Rockchip瑞芯微NPU 的第二代軟件棧核心由兩部分組成組件作用在本項(xiàng)目中的位置rknn-toolkit2模型轉(zhuǎn)換工具PC 端運(yùn)行把 ONNX 轉(zhuǎn)成.rknn模型轉(zhuǎn)換腳本examples/rknn_yolov5_demo/convert_rknn_demo/yolov5/onnx2rknn.pylibrknn_api端側(cè)運(yùn)行時(shí)推理庫板端運(yùn)行runtime/RK3588/Linux/librknn_api/對新手來說它的優(yōu)勢在于性能高、功耗低推理交給 NPU 硬件執(zhí)行CPU 幾乎不占用適合邊緣盒子、IPC 攝像頭等場景流程標(biāo)準(zhǔn)轉(zhuǎn)換 → 推理 → 后處理三步走官方 Demo 可直接編譯運(yùn)行適配廣同一套代碼支持 RK3562、RK3566/RK3568、RK3588 及 RV1106 系列芯片Linux 與 Android 均可運(yùn)行。?? 新手注意由于硬件限制Demo 默認(rèn)把 YOLOv5 的后處理部分移到 CPU 實(shí)現(xiàn)且附帶模型使用 relu 激活相比 silu 精度略降、性能大幅提升詳見examples/rknn_yolov5_demo/README_CN.md。二、項(xiàng)目結(jié)構(gòu)速覽YOLOv5 Demo 里有什么Demo 位于examples/rknn_yolov5_demo/核心文件一覽examples/rknn_yolov5_demo/ ├── convert_rknn_demo/yolov5/ # ONNX 轉(zhuǎn) RKNN 的轉(zhuǎn)換腳本 │ ├── onnx2rknn.py # 轉(zhuǎn)換入口 │ ├── onnx_models/yolov5s_relu.onnx │ └── dataset.txt # 量化校準(zhǔn)數(shù)據(jù)集列表 ├── model/ # 各平臺(tái)預(yù)轉(zhuǎn)換好的 .rknn 模型 │ ├── RK3562/ RK3566_RK3568/ RK3588/ │ ├── bus.jpg # 測試圖片 │ └── coco_80_labels_list.txt # COCO 80 類標(biāo)簽 ├── src/ │ ├── main.cc # 圖片檢測主程序 │ ├── main_video.cc # 視頻流檢測主程序 │ ├── preprocess.cc # letterbox / RGA 縮放預(yù)處理 │ └── postprocess.cc # 反量化 NMS ├── include/ │ ├── postprocess.h # NMS_THRESH、BOX_THRESH 等參數(shù) │ ├── preprocess.h │ └── rga_func.h └── utils/ # MPP 解碼/編碼、畫框工具關(guān)鍵點(diǎn)模型按芯片平臺(tái)分目錄存放如model/RK3588/yolov5s-640-640.rknn運(yùn)行時(shí)按自己板子選擇對應(yīng)目錄即可。三、模型轉(zhuǎn)換ONNX 轉(zhuǎn) RKNN 的最快 3 步法轉(zhuǎn)換腳本為examples/rknn_yolov5_demo/convert_rknn_demo/yolov5/onnx2rknn.py在 PC 上配合 rknn-toolkit2版本 ≥ 1.4.0使用。1. 修改目標(biāo)平臺(tái)參數(shù)打開onnx2rknn.py將platform改成你的芯片platform rk3566 # 可改為 rk356x / rk3588 等2. 確認(rèn)量化配置腳本中已給出推薦配置輸入640x640、mean 為 0、std 為 255即把 0~255 歸一化到 0~1并啟用INT8 量化do_quantizationTrue 校準(zhǔn)數(shù)據(jù)集dataset.txtrknn.config(mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformplatform) ret rknn.build(do_quantizationTrue, datasetDATASET) ret rknn.export_rknn(RKNN_MODEL_PATH) 量化需要校準(zhǔn)集dataset.txt內(nèi)為若干圖片路徑校準(zhǔn)集越貼近真實(shí)業(yè)務(wù)場景INT8 精度越穩(wěn)。3. 執(zhí)行轉(zhuǎn)換python onnx2rknn.py生成的.rknn模型輸出在rknn_models/目錄拷貝到板端model/平臺(tái)/目錄即可使用。 替換自訓(xùn)練模型時(shí)的兩大坑anchor 必須對齊Demo 后處理硬編碼了 YOLOv5 的三組 anchor見src/postprocess.cc中anchor0/anchor1/anchor2換模型不同步修改會(huì)導(dǎo)致檢測框解析錯(cuò)亂類別數(shù)與閾值COCO 80 類對應(yīng)include/postprocess.h中的OBJ_CLASS_NUM 80自定義類別需同步修改。四、推理主流程從圖片輸入到檢測框輸出主程序examples/rknn_yolov5_demo/src/main.cc的完整鏈路如下共 5 步步驟關(guān)鍵 API說明① 初始化rknn_init加載.rknn模型創(chuàng)建推理上下文② 查詢屬性rknn_query獲取輸入/輸出張量的尺寸、格式、量化 scale 與 zero-point③ 預(yù)處理letterbox / RGA縮放填充到 640x640默認(rèn)letterbox保持長寬比④ 推理rknn_inputs_set→rknn_run→rknn_outputs_getNPU 執(zhí)行前向計(jì)算⑤ 后處理post_process反量化 置信度過濾 NMS輸出檢測框letterbox 預(yù)處理參數(shù)怎么理解src/preprocess.cc中的letterbox()按最小縮放比縮放圖像并居中補(bǔ)邊避免拉伸變形——這正是 YOLOv5 訓(xùn)練時(shí)的預(yù)處理方式直接決定了檢測精度??s放比scale_w/scale_h和補(bǔ)邊量pads會(huì)傳入后處理用于把預(yù)測框映射回原圖坐標(biāo)// main.cc 中的調(diào)用 letterbox(img, resized_img, pads, min_scale, target_size);若只追求速度不在乎形變可選resize模式走 RGA 硬件加速追求精度請保持默認(rèn)letterbox。五、NMS 后處理詳解如何去掉重復(fù)的檢測框這是新手最容易困惑的一環(huán)。NPU 輸出的是80 個(gè)類別 × 每網(wǎng)格數(shù)百個(gè)候選框的量化張量必須經(jīng)過三層漏斗才能得到最終結(jié)果原始輸出(約上千候選) ── 置信度過濾 ── NMS去重 ── 最終檢測框 (反量化) (BOX_THRESH) (NMS_THRESH)1. 反量化把 INT8 還原成浮點(diǎn)量化模型輸出的是整型需按輸出屬性還原value (raw - zp) * scale。scale/zp 來自rknn_query的output_attrs[i].scale / .zppost_process()內(nèi)部已自動(dòng)處理。2. 兩個(gè)關(guān)鍵閾值include/postprocess.h#define OBJ_CLASS_NUM 80 // 類別數(shù)COCO #define NMS_THRESH 0.45 // IOU 閾值大于該值的重疊框被抑制 #define BOX_THRESH 0.25 // 置信度閾值低于該值的框直接丟棄BOX_THRESH0.25調(diào)高 → 框更少、誤檢更少但可能漏檢小目標(biāo)NMS_THRESH0.45調(diào)低 → 去重更激進(jìn)密集小目標(biāo)場景容易誤刪調(diào)高 → 保留更多框但同一目標(biāo)可能出現(xiàn)重復(fù)框。3. NMS 去重的核心邏輯src/postprocess.cc中的nms()按置信度降序遍歷同類框用CalculateOverlap()計(jì)算兩兩 IOU凡 IOU 超過NMS_THRESH的框直接標(biāo)記刪除order[j] -1——這就是經(jīng)典的Non-Maximum Suppression算法代碼約 40 行非常適合作為端側(cè) NMS 的參考實(shí)現(xiàn)。最后程序在原圖上用 OpenCV 畫出紅色邊框與類別置信度文字結(jié)果保存為out.jpg。六、編譯與運(yùn)行快速部署到你的開發(fā)板1. 一鍵交叉編譯修改build-linux_TARGET_PLATFORM.sh中的工具鏈路徑TOOL_CHAIN然后執(zhí)行腳本即可編譯配置見CMakeLists.txt已自動(dòng)鏈接 RKNN API、OpenCV、RGA、MPP 庫export TOOL_CHAIN~/opt/tool_chain/gcc-9.3.0-x86_64_aarch64-linux-gnu/host ./build-linux_RK3588.shAndroid 端則修改ANDROID_NDK_PATH后運(yùn)行build-android_TARGET_PLATFORM.sh。2. 推送到板端并運(yùn)行adb push install/rknn_yolov5_demo_Linux /userdata/ adb shell cd /userdata/rknn_yolov5_demo_Linux/ export LD_LIBRARY_PATH./lib ./rknn_yolov5_demo model/RK3588/yolov5s-640-640.rknn model/bus.jpg程序會(huì)先跑一次單幀輸出檢測詳情再循環(huán) 10 次統(tǒng)計(jì)平均耗時(shí)含后處理例如loop count 10 , average run XX ms。3. 進(jìn)階視頻流實(shí)時(shí)檢測src/main_video.cc支持 H.264/H.265 文件與 RTSP 流僅 Linux基于 MPP 硬解碼./rknn_yolov5_video_demo model/RK3588/yolov5s-640-640.rknn xxx.hevc 265 ./rknn_yolov5_video_demo model/RK3588/yolov5s-640-640.rknn RTSP_URL 265?? RK3562 目前僅支持 H.264 視頻流Android 暫不支持 RTSP。七、常見問題與調(diào)優(yōu)建議問題現(xiàn)象排查方向框位置整體偏移/錯(cuò)亂anchor 未對齊、letterbox 的pads/scale未傳入后處理漏檢增多調(diào)低BOX_THRESH如 0.15或更換非量化模型同一目標(biāo)多個(gè)框調(diào)低NMS_THRESH如 0.3精度明顯下降檢查量化校準(zhǔn)集是否貼合業(yè)務(wù)場景確認(rèn) std_values 與訓(xùn)練歸一化一致找不到 librga.so按板端 RGA 驅(qū)動(dòng)版本選擇對應(yīng)庫并加入LD_LIBRARY_PATH類別數(shù)對不上修改postprocess.h中OBJ_CLASS_NUM并替換標(biāo)簽文件結(jié)語至此你已經(jīng)掌握了RKNPU2 部署 YOLOv5 目標(biāo)檢測的完整鏈路onnx2rknn.py三步轉(zhuǎn)換出 RKNN 模型main.cc五步推理拿到檢測結(jié)果再用postprocess.cc中的反量化 雙閾值過濾 NMS 得到最終檢測框。接下來可以試著替換成自訓(xùn)練模型、接入相機(jī)或 RTSP 視頻流把檢測能力真正落地到你的邊緣設(shè)備中?!久赓M(fèi)下載鏈接】rknpu2項(xiàng)目地址: https://gitcode.com/gh_mirrors/rk/rknpu2創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考