實操教程:android camera nanodet 實時物體檢測的高效實現總結

極市導讀
本文介紹了配合高效的Android應用層體現nanodet的實時物體檢測的高效實現的總結,附有代碼地址。 >>加入極市CV技術交流群,走在計算機視覺的最前沿
0x0 起因
ncnn 是為移動端優(yōu)化的神經網絡推理框架 nanodet 是輕量級通用物體檢測算法
為了能跑得更快更好,ncnn 和 nanodet 費了很大功夫優(yōu)化模型結構和代碼實現
然而,只有配合高效的 android 應用層實現,才能將 ncnn nanodet 優(yōu)勢體現
否則,底層辛辛苦苦省下的時間,很容易被上層低效的實現浪費
似乎沒找到靠譜的代碼,那就自己寫個吧
https://github.com/Tencent/ncnngithub.com
https://github.com/nihui/opencv-mobilegithub.com
https://github.com/RangiLyu/nanodetgithub.com
0x1 源代碼傳送門
不廢話,先上源碼和APK包下載鏈接
nihui/ncnn-android-nanodetgithub.com
https://github.com/nihui/ncnn-android-nanodet/releases/download/v1/com.tencent.nanodetncnn-release.apkgithub.com

0x2 NdkCamera 取幀,畫圖和渲染

Camera2 (傳統(tǒng)方式)
java 初始化和設置相機,創(chuàng)建 ImageReader 做預覽回調 java OnImageAvailable 轉換為 rgba / Bitmap java 通過 JNI 調用 C++ 實現的 nanodet 檢測函數 c++ nanodet 推理 java 通過 JNI 返回檢測框信息,用 Canvas 在 Bitmap 畫框畫字,更新 重復 3-5

NdkCamera
c++ 初始化和設置相機,創(chuàng)建 AImageReader 做預覽回調 java 通過 JNI 設置顯示的 SurfaceView ANativeWindow c++ onImageAvailable 獲得 yuv420sp,旋轉,轉 RGB c++ nanodet 推理 c++ opencv-mobile 畫框畫字,更新 ANativeWindow buffer 重復 3-5
相較于 Camera2 傳統(tǒng)實現流程,主要有以下優(yōu)勢
每幀的處理循環(huán)完全用 c++ 實現,避免 JNI 與 java api 的數據傳輸 使用 ncnn 優(yōu)化的 yuv420sp 旋轉,轉 RGB 函數實現,更高效 使用 opencv-mobile 畫框畫字,更高效 ANativeWindow buffer 到屏幕的縮放由硬件完成
也要說下缺點
需要 android 7.0 或以上系統(tǒng) 不兼容很老的 LEGACY camera interface
總之,很老的手機就別折騰實時檢測了吧,承受著不該承受的計算壓力。。
NdkCamera.h 白嫖攻略
光明正大地把app/src/main/jni/ndkcamera.h和app/src/main/jni/ndkcamera.cpp兩個文件 Ctrl+C Ctrl+V,配合鏈接 ncnn 和 opencv-mobile
class NdkCamera{public:// facing 0=front 1=backint open(int camera_facing = 0);void close();virtual void on_image(const cv::Mat& rgb) const;};
這個類我已經做的足夠簡單易懂了,把 on_image 自己實現下
用的時候先 open,就會自動調用你寫的 on_image,rgb 是當前預覽的幀,隨你怎么用,比如做做檢測,或者畫畫什么的
要切換攝像頭就先 close,重新 open
0x3 高效的 NanoDet 推理技巧
nanodet 的模型是可以動態(tài) shape 輸入的,打開 param 文件把 Intep 的固定參數改為 scale_factor
比如 480x640 的圖片,可以直接 480x640 輸入給模型推理,而不需要先 pad 到 640x640,節(jié)約了 25% 的運算量
7個nanodet模型,打開 param 文件把輸出 blob 名字全部改成了統(tǒng)一的cls_pred_stride_8,這樣代碼里寫ex.extract("cls_pred_stride_8", cls_pred);就能對付全部模型了
設置內存池 設置使用大核心 設置線程數等于大核心數
會比默認效率更高些(正在計劃默認啟用,將來的ncnn版本不設置就比較好用了)
0x4 其實還可以更加優(yōu)化
比如
針對 nanodet 輸入尺寸,先在 yuv420sp resize 而不是 rgb resize ANativeWindow buffer 使用 RGB565 進一步減少帶寬 NdkCamera 中的 yuv420sp 旋轉和轉換 RGB 復用內存,而不是每次申請 編譯git最新版 ncnn 代碼
給你們留點活呀!
歡迎加群交流呀:QQ群號和密碼見 ncnn github 首頁 README
推薦閱讀
2021-02-28
2021-03-08
2021-03-02

# CV技術社群邀請函 #
備注:姓名-學校/公司-研究方向-城市(如:小極-北大-目標檢測-深圳)
即可申請加入極市目標檢測/圖像分割/工業(yè)檢測/人臉/醫(yī)學影像/3D/SLAM/自動駕駛/超分辨率/姿態(tài)估計/ReID/GAN/圖像增強/OCR/視頻理解等技術交流群
每月大咖直播分享、真實項目需求對接、求職內推、算法競賽、干貨資訊匯總、與 10000+來自港科大、北大、清華、中科院、CMU、騰訊、百度等名校名企視覺開發(fā)者互動交流~

