1. 前言
通过前两篇文章 Android 导入ncnn-android-yolov8-seg : 实现人体识别和人像分割 、Android ncnn-android-yolov8-seg源码解析 : 实现人像分割 ,我们已经跑起来了程序,也分析了其源码。
接下来,这篇文章我们来实战一下,抽取出Demo的核心代码,在自己的项目中,使用Java层的Camera API,在JNI层使用OpenCV+YOLOv8+NCNN,来实现人体识别和人像分割功能。
实现效果如下,整个图像的是相机的原图,左上角部分,是我们进行人像识别、人像分割后,处理得到的图像 (未做镜像处理,所以暂时和原图左右是相反的)
>>> 本文的源码demo可以直接看这里 :
Android 基于 OpenCV+YOLOv8+NCNN 实现人像分割 Demo 源码下载
2. 新建项目
2.1 新建主项目
2.2 新建 Native library
2.3 在app中添加MyNcnnLib依赖
implementation(project(mapOf("path" to ":MyNcnnLib")))
2.4 配置NDK版本
记得在项目根目录下的local.properties中,配置NDK版本,这里的NDK版本需要在NDK16-NDK20之间
# 这里的路径需修改为你电脑中ndk的具体路径 ndk.dir=C\:\Developer\Android_SDK\ndk\20.0.5594570
3. 接入OpenCV+YOLOv8+NCNN
3.1 导入NCNN和OpenCV
我们将ncnn-20221128-android-vulkan和opencv-mobile-4.6.0-android复制到cpp文件夹下
3.2 复制cpp文件
将yolo.cpp、yolo.h复制到cpp文件夹下
3.3 配置Cmake
新版Android Studio中CMakeLists.txt的位置和Android Studio 3.6中CMakeLists.txt的路径位置不一样,所以CMakeLists.txt在设置配置的时候,设置的路径也是不一样的。
初始的CMakeLists.txt
cmake_minimum_required(VERSION 3.22.1) project("myncnnlib") add_library(${ CMAKE_PROJECT_NAME} SHARED myncnnlib.cpp) target_link_libraries(${ CMAKE_PROJECT_NAME} android log)
配置后的CMakeLists.txt
cmake_minimum_required(VERSION 3.22.1) project("myncnnlib") set(OpenCV_DIR ${ CMAKE_SOURCE_DIR}/opencv-mobile-4.6.0-android/sdk/native/jni) find_package(OpenCV REQUIRED core imgproc) set(ncnn_DIR ${ CMAKE_SOURCE_DIR}/ncnn-20221128-android-vulkan/${ ANDROID_ABI}/lib/cmake/ncnn) find_package(ncnn REQUIRED) add_library(${ CMAKE_PROJECT_NAME} SHARED myncnnlib.cpp yolo.cpp) target_link_libraries(${ CMAKE_PROJECT_NAME} ncnn camera2ndk mediandk ${ OpenCV_LIBS} android log)
4. 创建JNI接口
4.1 新建JNI接口
在NcnnNativeLib.kt中,新增两个JNI方法
/** * 初始化NCNN * * @return 是否成功 */ external fun load(mgr: AssetManager, modelid: Int, cpugpu: Int): Boolean /** * 人像检测 * */ external fun detect(data: ByteArray?, width: Int, height: Int, cameraId: Int): ByteArray
4.2 cpp中增加对应JNIf方法
在myncnnlib.cpp中,增加对应的JIN方法
extern "C" JNIEXPORT jboolean JNICALL Java_com_heiko_myncnnlib_NativeLib_load(JNIEnv *env, jobject thiz, jobject assetManager, jint modelid, jint cpugpu) { } extern "C" JNIEXPORT jbyteArray JNICALL Java_com_heiko_myncnnlib_NativeLib_detect(JNIEnv *env, jobject thiz, jbyteArray data_, jint w, jint h, jint camera_id) { }
4.3 声明include
#include#include #include #include #include #include #include "opencv2/opencv.hpp" #include #include #include "yolo.h" static Yolo *g_yolo = 0; static ncnn::Mutex lock;
4.4 加载模型
这里将Demo中的loadModel中的代码,全部拷贝过来
extern "C" JNIEXPORT jboolean JNICALL Java_com_heiko_myncnnlib_NativeLib_load(JNIEnv* env, jobject thiz, jobject assetManager, jint modelid, jint cpugpu) { if (modelid < 0 || modelid > 6 || cpugpu < 0 || cpugpu > 1) { return JNI_FALSE; } AAssetManager* mgr = AAssetManager_fromJava(env, assetManager); __android_log_print(ANDROID_LOG_DEBUG, "ncnn", "loadModel %p", mgr); const char* modeltypes[] = { "n", "s", }; const int target_sizes[]
猜你喜欢
网友评论
- 搜索
- 最新文章
- 热门文章