Android JNI 使用assets加载dlib特征点文件shape_predictor

Android JNI 使用assets加载dlib特征点文件shape_predictor

本文介绍如何在jni中加载apk的assets文件夹中的shape_predictor_68_face_landmarks.dat

在NDK中,google提供了AAssetManager_fromJava来获得Native中对应的AAssetManager,使用它的相关api可以将指针(char*)指向assets文件的内存地址

dlib有一个重载函数deserialize(serializable_type& item, std::istream& in),因此我们想要从内存中加载dlib特征定位文件的话,就可以先将char*转换为istream后使用这个函数加载

jni代码

#include <android/asset_manager_jni.h>

struct membuf : std::streambuf {
    membuf(char* begin, char* end) {
        this->setg(begin, begin, end);
    }
};

dlib::shape_predictor pose_model;

extern "C"
JNIEXPORT void JNICALL
Java_com_gavinandre_demo_MainActivity_loadShapePredictor(
        JNIEnv *env, jclass type, jobject assetManager, jstring fileName) {

    const char *file_name = env->GetStringUTFChars(fileName, nullptr);
    env->ReleaseStringUTFChars(fileName, file_name);

    //get AAssetManager
    AAssetManager *native_asset = AAssetManager_fromJava(env, assetManager);

    //open file
    AAsset *assetFile = AAssetManager_open(native_asset, file_name, AASSET_MODE_BUFFER);
    //get file length
    size_t file_length = static_cast<size_t>(AAsset_getLength(assetFile));
    char *model_buffer = (char *) malloc(file_length);
    //read file data
    AAsset_read(assetFile, model_buffer, file_length);
    //the data has been copied to model_buffer, so , close it
    AAsset_close(assetFile);

    //LOGI("asset file length %d", file_length);

    //char* to istream
    membuf mem_buf(model_buffer, model_buffer + file_length);
    std::istream in(&mem_buf);

    //load shape_predictor_68_face_landmarks.dat from memory
    dlib::deserialize(pose_model,in);

    //free malloc
    free(model_buffer);
}

在java端使用

//声明jni函数
public native void loadShapePredictor(AssetManager assetManager, String fileName);

//使用方式
loadShapePredictor(getAssets(), "shape_predictor_68_face_landmarks.dat");

参考

https://www.cnblogs.com/willhua/p/9692529.html

https://stackoverflow.com/questions/52610460/android-jni-load-dlib-shape-predictor-file

https://stackoverflow.com/questions/7781898/get-an-istream-from-a-char/7782037#7782037

发布了174 篇原创文章 · 获赞 119 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/lj402159806/article/details/90713676