【问题标题】:Android native file read from assets folder by tflite BuildFromFile()tflite BuildFromFile() 从 assets 文件夹中读取的 Android 本机文件
【发布时间】:2020-12-13 08:49:08
【问题描述】:

我有 Android 本机代码(C++ 共享对象),想在创建 APK 时将 read 模型文件保存在 assets 文件夹中。

Tensorflow Lite 有两个 API:FromFile 和 FromBuffer

static std::unique_ptr<FlatBufferModel> BuildFromFile(const char* filename, ErrorReporter* error_reporter);

static std::unique_ptr<FlatBufferModel> BuildFromBuffer(const char* buffer, size_t buffer_size, ErrorReporter* error_reporter);

使用以下代码我可以访问 FromBuffer:

Java代码:

private AssetManager mgr;

// Get mgr 
mgr = getResources().getAssets();

C++代码:

AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
const char* filename = (const char*)NULL;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
    AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
    char buf[BUFSIZ];
    int nb_read = 0;
    FILE* out = fopen(filename, "w");
    while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
        fwrite(buf, nb_read, 1, out);
    fclose(out);
    AAsset_close(asset);
}
AAssetDir_close(assetDir);

任何想法,如何访问assets文件夹以使用BuildFromFile

【问题讨论】:

    标签: android c++ tensorflow android-ndk tensorflow-lite


    【解决方案1】:

    我不认为你可以在不将资产文件复制到本地文件的情况下使用BuildFromFile(这相当于你上面所做的,然后BuildFromBuffer在这种情况下更方便)。

    如果你想避免内存复制,你可以这样做:

    1. (Java) 通过内存映射加载模型。
        AssetFileDescriptor fileDescriptor = getResources().getAssets().openFd(filePath);\
        FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());\
        FileChannel fileChannel = inputStream.getChannel();\
        long startOffset = fileDescriptor.getStartOffset();\
        long declaredLength = fileDescriptor.getDeclaredLength();\
        MappedByteBuffer modelBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
    
    1. (Java)通过jni将映射文件传递给C++,比如定义如下方法:
        private static native void initJniWithByteBuffer(ByteBuffer modelBuffer)
    
    1. (C++) 使用缓冲文件来初始化你的模型:
        Java_xxxxxx_initJniWithByteBuffer(JNIEnv* env, jclass thiz, jobject model_buffer) {\
          char* buffer = static_cast<char*>(env->GetDirectBufferAddress(model_buffer));\
          size_t buffer_size = static_cast<size_t>(env->GetDirectBufferCapacity(model_buffer));\
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多