作者丨nihui@知乎(已授权)
来源丨https://zhuanlan.zhihu.com/p/356991989
编辑丨极市平台
导读
本文介绍了配合高效的Android应用层体现nanodet的实时物体检测的高效实现的总结,附有代码地址。
0x0 起因
ncnn 是为移动端优化的神经网络推理框架
nanodet 是轻量级通用物体检测算法
为了能跑得更快更好,ncnn 和 nanodet 费了很大功夫优化模型结构和代码实现
然而,只有配合高效的 android 应用层实现,才能将 ncnn nanodet 优势体现
否则,底层辛辛苦苦省下的时间,很容易被上层低效的实现浪费
似乎没找到靠谱的代码,那就自己写个吧
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 (传统方式)
java 初始化和设置相机,创建 ImageReader 做预览回调
java OnImageAvailable 转换为 rgba / Bitmap
java 通过 JNI 调用 C++ 实现的 nanodet 检测函数
c++ nanodet 推理
java 通过 JNI 返回检测框信息,用 Canvas 在 Bitmap 画框画字,更新
重复 3-5
NdkCamera
c++ 初始化和设置相机,创建 AImageReader 做预览回调
java 通过 JNI 设置显示的 SurfaceView ANativeWindow
c++ onImageAvailable 获得 yuv420sp,旋转,转 RGB
c++ nanodet 推理
c++ opencv-mobile 画框画字,更新 ANativeWindow buffer
重复 3-5
相较于 Camera2 传统实现流程,主要有以下优势
每帧的处理循环完全用 c++ 实现,避免 JNI 与 java api 的数据传输
使用 ncnn 优化的 yuv420sp 旋转,转 RGB 函数实现,更高效
使用 opencv-mobile 画框画字,更高效
ANativeWindow buffer 到屏幕的缩放由硬件完成
也要说下缺点
需要 android 7.0 或以上系统
不兼容很老的 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=back int 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 的模型是可以动态 shape 输入的,打开 param 文件把 Intep 的固定参数改为 scale_factor
比如 480x640 的图片,可以直接 480x640 输入给模型推理,而不需要先 pad 到 640x640,节约了 25% 的运算量
7个nanodet模型,打开 param 文件把输出 blob 名字全部改成了统一的cls_pred_stride_8
,这样代码里写ex.extract("cls_pred_stride_8", cls_pred);
就能对付全部模型了
设置内存池
设置使用大核心
设置线程数等于大核心数
会比默认效率更高些(正在计划默认启用,将来的ncnn版本不设置就比较好用了)
0x4 其实还可以更加优化
比如
针对 nanodet 输入尺寸,先在 yuv420sp resize 而不是 rgb resize
ANativeWindow buffer 使用 RGB565 进一步减少带宽
NdkCamera 中的 yuv420sp 旋转和转换 RGB 复用内存,而不是每次申请
编译git最新版 ncnn 代码
本文仅做学术分享,如有侵权,请联系删文。
下载1
在「计算机视觉工坊」公众号后台回复:深度学习,即可下载深度学习算法、3D深度学习、深度学习框架、目标检测、GAN等相关内容近30本pdf书籍。
下载2
在「计算机视觉工坊」公众号后台回复:计算机视觉,即可下载计算机视觉相关17本pdf书籍,包含计算机视觉算法、Python视觉实战、Opencv3.0学习等。
下载3
在「计算机视觉工坊」公众号后台回复:SLAM,即可下载独家SLAM相关视频课程,包含视觉SLAM、激光SLAM精品课程。
重磅!计算机视觉工坊-学习交流群已成立
扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。
同时也可申请加入我们的细分方向交流群,目前主要有ORB-SLAM系列源码学习、3D视觉、CV&深度学习、SLAM、三维重建、点云后处理、自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、深度估计、学术交流、求职交流等微信群,请扫描下面微信号加群,备注:”研究方向+学校/公司+昵称“,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进去相关微信群。原创投稿也请联系。
▲长按加微信群或投稿
▲长按关注公众号
3D视觉从入门到精通知识星球:针对3D视觉领域的知识点汇总、入门进阶学习路线、最新paper分享、疑问解答四个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近3000星球成员为创造更好的AI世界共同进步,知识星球入口:
学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
圈里有高质量教程资料、可答疑解惑、助你高效解决问题
觉得有用,麻烦给个赞和在看~