首页 > 解决方案 > 将什么传递给 Android 的 NDK 以便可以使用 OpenCV 加载图像?

问题描述

信息

我有一个 Android NDK / OpenCV 项目(运行本机 C++ 代码)。

我正在尝试将图像加载到 NDK,所以我将图像加载为位图,这样我就可以获得它的路径。

我不想将整个图像传递给 NDK(如这个答案这个答案或其他),我只想将一个字符串(例如图像路径)或一个指针或类似的东西传递给 NDK,然后从NDK 与 OpenCV。

我尝试使用OpenCV 的人脸检测示例作为参考,但它并没有真正做我想做的事情。

为了在 Java 中获取路径字符串,我尝试了这个:

Uri uri = data.getData();
String imagePath = uri.getEncodedPath();

或这个:

Cursor imageCursor;
int imageNameIndex, imageSizeIndex;
Uri uri = data.getData();
imageCursor = getContentResolver().query(uri, null, null, null, null);
imageNameIndex = imageCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
String imagePath = imageCursor.getString(nameIndex);

或者那个:

String imageFullPath = Environment.getExternalStorageDirectory() + "/Pictures/" + imagePath;

或者那个:

String imageFullPath = Environment.DIRECTORY_PICTURES + "/" + imagePath;

这让我得到了像/storage/emulated/0/Pictures/my-image.jpg,Pictures/my-image.jpg或.my-image.jpg/document/image%3A167

然后我将字符串传递给 NDK(将其转换为char *)并尝试使用 OpenCV 在 C++ 上加载图像imread

Mat image = imread(image_path, IMREAD_COLOR);

所有上述试验都会产生一个空Mat对象(所有int值相等0且指针为NULL)。

我也尝试过使用指针的类似方法。

问题

这是一个 OpenCV 问题吗?我应该Mat以某种方式初始化吗?

如果不是,我应该将什么字符串/指针传递给 NDK 以便它可以加载图像?

标签: androidandroid-studioopencvimage-processingandroid-ndk

解决方案


传球指针

Java端:

Activity.java

// create a mat object with CvType.CV_8UC4, for Android's RGBA_8888
Mat passToNativeMat = new Mat(height, width, CvType.CV_8UC4);

// convert (for example) a bitmap image to Mat object
Utils.bitmapToMat(bitmap, passToNativeMat);

// get the native address of the Mat object created
long passToNativeMatAddress = passToNativeMat.getNativeObjAddr();

// call the Native function
String imageToJNIResult = imageToJNI(passToNativeMatAddress);

// native declarations
public native String imageToJNI(long imagePointer);

本机方面:

native-lib.cpp

extern "C"
JNIEXPORT jstring JNICALL
Java_package_activity_imageToJNI(
        JNIEnv* env,
        jobject thiz,
        jlong imagePointer) {

    Mat& image_in_native = *(Mat*) imagePointer;

    // do something with image Mat object

    string return_string = "Return string";

    return env->NewStringUTF(return_string.c_str());

}

传递字节数组

Java端:

public native String byteToJNI(byte[] myArray);

本机方面:

extern "C" JNIEXPORT jstring JNICALL
Java_package_activity_byteToJNI(
        JNIEnv* env,
        jobject thiz,
        jbyteArray array) {

    Mat * mat = ByteToMat(array);

    string return_string = "Return string";

    return env->NewStringUTF(return_string.c_str());

}

推荐阅读