前言
预备内容:
ncnn笔记:01)windows+AndriodStudio在安卓机上快速构建一个深度学习分类模型
ncnn笔记:02)ncnn之JNI入门初窥
准备预训练模型文件
ncnn官方提供的retinaface权重及参数文件为
mnet.25-opt.bin mnet.25-opt.param
下载地址:https://github.com/nihui/ncnn-assets/tree/master/models,但笔者使用该权重在ubuntu上测试会出现如下错误
javis@javis-HP-280-Pro-G2-MT:~/soft/ncnn/build/examples$ ./retinaface /tmp/p.jpeg
parse magic failed
network graph not ready
find_blob_index_by_name data failed
find_blob_index_by_name face_rpn_cls_prob_reshape_stride32 failed
find_blob_index_by_name face_rpn_bbox_pred_stride32 failed
find_blob_index_by_name face_rpn_landmark_pred_stride32 failed
浮点数例外 (核心已转储)
解决方法可参考笔者在github上提交的issue
创建nativa c++项目
如下图所示,选择nativa c++,c++ standard选择c++11
准备ncnn库文件
本次仅使用cpu做测试,因此无需vulkan,下载通用包ncnn-android-lib.zip解压到cpp目录下,其实只保留armeabi-v7a即可,其为大部分Android机支持类型,不同机型参考
准备模型文件
在main文件下新建Assets目录,并把mnet.25-opt.bin mnet.25-opt.param放到此目录下
编写jni文件
编写规则可参考项目默认创建的native-lib.cpp,此次需提供2个jni接口
- Init:用于加载检测模型
- Detect:用于检测图片中的人脸
在java的目录下新建一个java类,编写接口如下
package com.example.retainfacencnn;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
public class RetinaFace {
static {
System.loadLibrary("retinafacencnn");
}
//加载模型接口 AssetManager用于加载assert中的权重文件
public native boolean Init(AssetManager mgr);
//模型检测接口 其值=4-box + 5-landmark
public native float[] Detect(Bitmap bitmap);
}
生成对应的jni文件retinaface_jni.cpp
加载模型接口
extern "C" JNIEXPORT jboolean JNICALL
Java_com_example_retainfacencnn_RetinaFace_Init(JNIEnv *env, jobject thiz, jobject assetManager) {
AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);
//init param
int ret = retinaface.load_param(mgr, "mnet.25-opt.param");
if (ret != 0) {
__android_log_print(ANDROID_LOG_DEBUG, "RetinaFace", "load_param failed");
return