實(shí)踐教程 | 詳細(xì)記錄insightface的SCRFD人臉檢測(cè)ncnn實(shí)現(xiàn)

來(lái)源 | https://zhuanlan.zhihu.com/p/372332267
編輯 | 極市平臺(tái)
極市導(dǎo)讀
?本文詳細(xì)記錄了insightface的SCRFD人臉檢測(cè)ncnn實(shí)現(xiàn)過(guò)程。>>加入極市CV技術(shù)交流群,走在計(jì)算機(jī)視覺(jué)的最前沿
0x0 SCRFD 人臉檢測(cè)
SCRFD 是高效率高精度人臉檢測(cè)算法,2021年5月剛發(fā)出來(lái)的,速度和精度相比其他算法都有提升!

deepinsight / insightface地址:https://github.com/deepinsight/insightface/tree/master/detection/scrfd
Sample and Computation Redistribution for Efficient Face Detection地址:https://arxiv.org/abs/2105.04714

總所周知,insightface 是業(yè)界名氣響當(dāng)當(dāng)?shù)娜四標(biāo)惴ㄩ_(kāi)源項(xiàng)目,也是 mxnet 框架茍到今日的重要原因。
現(xiàn)在,pytorch 大法好!
0x1 緣由
那天下午,insightface 作者 過(guò)客 大佬小窗敲了我

SCRFD 是用 pytorch + mmdet 做的,看看 github 上好像也缺一個(gè) mmdet 部署 ncnn 的項(xiàng)目
這里就用 SCRFD 作為例子,介紹下如何轉(zhuǎn)換模型,后處理實(shí)現(xiàn)細(xì)節(jié),android 和 web 端移植
0x2 配環(huán)境
系統(tǒng)是 fedora 34,gcc 11.1.1,python 3.9,nvidia-driver 465.27,cuda 11.3
安裝 pytorch torchvision onnx-simplifier
pip?install?-U?torch?--user
pip?install?-U?torchvision?--user
pip?install?-U?onnx-simplifier?--user
安裝 thrust
git?clone?https://github.com/NVIDIA/thrust.git
cd?thrust
git?submodule?update?--init?--recursive
mkdir?build
cd?build
cmake?-DTHRUST_ENABLE_HEADER_TESTING=OFF?-DTHRUST_ENABLE_TESTING=OFF?-DTHRUST_ENABLE_EXAMPLES=OFF?..
make?-j8
sudo?make?install
我的 fedora 系統(tǒng)得改 /usr/share/cmake/Modules/CMakeDetermineCUDACompiler.cmake 注釋190行 FATAL_ERROR 才可正常編譯
安裝 mmcv
export?MMCV_CUDA_ARGS='-ccbin=/usr/bin/cuda-gcc'
pip?install?mmcv-full?--user
我的 fedora 系統(tǒng)得改 /home/nihui/.local/lib/python3.9/site-packages/torch/utils/cpp_extension.py include_paths 附加 /usr/include/cuda 才可正常編譯
安裝依賴和 mmdet
按照 SCRFD README 步驟進(jìn)行即可
git?clone?https://github.com/deepinsight/insightface.git
cd?insightface/detection/scrfd
pip?install?-r?requirements/build.txt?--user
pip?install?-v?-e?.?--user
0x3 轉(zhuǎn)模型
下載 pth模型
下載 pretrained 模型 SCRFD_500M
deepinsight/insightface:https://github.com/deepinsight/insightface/tree/master/detection/scrfd%23pretrained-models


pytorch 測(cè)試模型
python?demo/image_demo.py?nihui.jpg?configs/scrfd/scrfd_500m.py?model.pth
成功啦

導(dǎo)出 onnx
python?tools/scrfd2onnx.py?configs/scrfd/scrfd_500m.py?model.pth?--shape?640?640?--input-img?nihui.jpg
使用固定 shape 輸入可以更好的清除 onnx 膠水op,也不影響后續(xù) ncnn 的動(dòng)態(tài) shape 輸入推理,因此推薦總是使用固定 shape 導(dǎo)出 onnx
onnx 文件會(huì)被存放在 onnx/scrfd_500m_shape640x640.onnx
onnx 轉(zhuǎn) ncnn
onnx2ncnn?scrfd_500m_shape640x640.onnx?scrfd_500m.param?scrfd_500m.bin
ncnnoptimize?scrfd_500m.param?scrfd_500m.bin?scrfd_500m-opt.param?scrfd_500m-opt.bin?1
沒(méi)有任何報(bào)錯(cuò),groupnorm 也能正常轉(zhuǎn)換出來(lái)
手改 param,支持動(dòng)態(tài) shape 推理
Interp 固定參數(shù)改為按系數(shù)放大

手改 param,head 輸出部分修復(fù)
檢測(cè)模型中,經(jīng)常看到最后輸出會(huì)有 transpose reshape 這樣的組合,對(duì)輸出數(shù)據(jù)做重排

實(shí)際可以不做重排,節(jié)省重排的時(shí)間,直接對(duì)原本的數(shù)據(jù)布局做后處理,關(guān)注數(shù)據(jù)布局的物理意義
score 的 shape channel 為 2,即 2種 anchor ratio * 1個(gè) prob人臉?lè)诸?lèi)置信度 bbox 的 shape channel 為 8,即 2種 anchor ratio * 4個(gè) bbox偏移 kps 的 shape channel 為 20,即 2種 anchor ratio * 5個(gè) xy點(diǎn)坐標(biāo)偏移 score bbox kps 的 shape width height,即 xy 就是當(dāng)前圖片里對(duì)應(yīng)的 anchor grid xy 下標(biāo)
Permute
Reshape
Reshape
替換為 Noop
Noop
Noop
Noop


改完后再執(zhí)行一遍 ncnnoptimize,能自動(dòng)清除 Noop
ncnnoptimize?scrfd_500m-opt.param?scrfd_500m-opt.bin?scrfd_500m-opt2.param?scrfd_500m-opt2.bin?1
0x4 實(shí)現(xiàn) SCRFD
實(shí)現(xiàn)動(dòng)態(tài)輸入
SCRFD 的超參數(shù)都在 insightface/detection/scrfd/configs/scrfd/scrfd_500m.py 文件里
看 anchor_generator 設(shè)置可以得知,anchor 最小為 16x16,最大為 512x512,因此將圖片縮放到長(zhǎng)邊為 640 是合理的
anchor stride 最大為 32,因此將輸入圖片的長(zhǎng)寬補(bǔ)到 32 倍數(shù)是合理的
預(yù)處理的 mean norm 值可從 transforms 設(shè)置中獲得
實(shí)現(xiàn)后處理
后處理實(shí)現(xiàn)的時(shí)候,以之前 retinaface.cpp 代碼做模板,針對(duì) mmdet SCRFD 的配置做些修改
anchor 的 center 起始值改為 (0,0),這是 mmdet 默認(rèn)配置,參考 insightface/detection/scrfd/mmdet/core/anchor/anchor_generator.py bbox 和關(guān)鍵點(diǎn)的計(jì)算,retinaface 的計(jì)算類(lèi)似 mmdet 的 delta_xywh_bbox_coder,SCRFD 的計(jì)算方式是 anchor_center + x * stride,參考 insightface/detection/scrfd/mmdet/models/dense_heads/scrfd_head.py_get_bboxes_single()函數(shù)
https://github.com/Tencent/ncnn/blob/master/examples/scrfd.cppgithub.com/Tencent/ncnn/blob/master/examples/scrfd.cpp
0x5 實(shí)現(xiàn) android 攝像頭實(shí)時(shí)檢測(cè)
基于模板工程
nihui/ncnn-android-nanodet:https://github.com/nihui/ncnn-android-nanodet

全局字符串替換 nanodet 為 scrfd
修改 app/src/main/jni/scrfdncnn.cpp 中的 void MyNdkCamera::on_image_render(cv::Mat& rgb) const實(shí)現(xiàn),替換為調(diào)用 scrfd 檢測(cè)scrfd.cpp 直接從 examples/scrfd.cpp 拿來(lái),封裝為類(lèi), ncnn::Mat::from_pixels_resize的 pixel 類(lèi)型從 PIXEL_BGR2RGB 改為 PIXEL_RGB把 scrfd 的全部模型都轉(zhuǎn)出來(lái),手改 param 統(tǒng)一了輸出層的 blob 名字為 bbox_8 bbox_16 bbox_32 這樣子,放在 assets 文件夾里 app/src/main/jni/scrfdncnn.cpp 和 app/src/main/res/values/strings.xml 文件里增加各個(gè)模型的名字
nihui/ncnn-android-scrfd:https://github.com/nihui/ncnn-android-scrfd
外網(wǎng)android apk安裝包下載:
https://github.com/nihui/ncnn-android-scrfd/releases/download/v1/com.tencent.scrfdncnn-release.apk
有關(guān)鍵點(diǎn)的2.5g模型在手機(jī)上可以實(shí)時(shí)檢測(cè)

0x6 實(shí)現(xiàn) web 攝像頭實(shí)時(shí)檢測(cè)
基于模板工程
nihui/ncnn-webassembly-nanodet:https://github.com/nihui/ncnn-webassembly-nanodet

全局字符串替換 nanodet 為 scrfd
修改 scrfdncnn.cpp 中的 static void on_image_render(cv::Mat& rgba)實(shí)現(xiàn),替換為調(diào)用 scrfd 檢測(cè)scrfd.cpp 直接從 examples/scrfd.cpp 拿來(lái),封裝為類(lèi), ncnn::Mat::from_pixels_resize的 pixel 類(lèi)型從 PIXEL_BGR2RGB 改為 PIXEL_RGBA2RGB把 scrfd_500m 模型放在 assets 文件夾里
https://nihui/ncnn-webassembly-scrfd
外網(wǎng)直接體驗(yàn)網(wǎng)址:
https://nihui.github.io/ncnn-webassembly-scrfd
i5-8250U 筆記本電腦 firefox 瀏覽器里 web 實(shí)時(shí)檢測(cè)

0x7 總結(jié)
最耗費(fèi)精力的是實(shí)現(xiàn)后處理,因?yàn)檫@需要一些 mmdet 和算法本身的知識(shí),這也許是不懂算法不會(huì)訓(xùn)模型的算法優(yōu)化工程師唯一的門(mén)檻 android 和 web 端都準(zhǔn)備好了模板工程,以及很方便的 on_image_render接口,配備了 opencv 和 ncnn 預(yù)編譯庫(kù),從 linux cpp 移植輕松許多web 端檢測(cè)兼容任意pc和手機(jī)瀏覽器,包括qq/微信內(nèi)置的webview,chrome體驗(yàn)最佳 ncnn 的主頁(yè) readme 有 qq 群,歡迎加入。
如果覺(jué)得有用,就請(qǐng)分享到朋友圈吧!
公眾號(hào)后臺(tái)回復(fù)“transformer”獲取最新Transformer綜述論文下載~

#?CV技術(shù)社群邀請(qǐng)函?#

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

