
极市导读
本文介绍了配合高效的Android应用层体现nanodet的实时物体检测的高效实现的总结,附有代码地址。 >>加入极市CV技术交流群,走在计算机视觉的最前沿
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 代码
给你们留点活呀!
公众号后台回复“数据集”获取30+深度学习数据集下载~

# CV技术社群邀请函 #

备注:姓名-学校/公司-研究方向-城市(如:小极-北大-目标检测-深圳)
即可申请加入极市目标检测/图像分割/工业检测/人脸/医学影像/3D/SLAM/自动驾驶/超分辨率/姿态估计/ReID/GAN/图像增强/OCR/视频理解等技术交流群
每月大咖直播分享、真实项目需求对接、求职内推、算法竞赛、干货资讯汇总、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企视觉开发者互动交流~
