Issue
info
I have an Android NDK / OpenCV project (running native c++ code).
I'm trying to load an image to the NDK, so I'm loading an image as a bitmap, so I can get it's path.
Instead of passing the whole image to the NDK (like this answer, this answer or others), I want to just pass a string (e.g. the image path) or a pointer or something like this to the NDK, and read the image from the NDK with OpenCV.
I tried to use OpenCV's Face Detection example as reference, but it doesn't really do what I'm trying to do.
To get the path string in Java I tried this:
Uri uri = data.getData();
String imagePath = uri.getEncodedPath();
Or this:
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);
Or that:
String imageFullPath = Environment.getExternalStorageDirectory() + "/Pictures/" + imagePath;
Or that:
String imageFullPath = Environment.DIRECTORY_PICTURES + "/" + imagePath;
which got me strings like /storage/emulated/0/Pictures/my-image.jpg
, Pictures/my-image.jpg
, my-image.jpg
or /document/image%3A167
.
Then I'm passing the string to the NDK (convert it to char *
) and try to load an image on C++ with OpenCV's imread
:
Mat image = imread(image_path, IMREAD_COLOR);
All of the above trials result in an empty Mat
object (all int
values equal 0
and pointers are NULL
).
I also tried similar approach with pointers.
question
Is this an OpenCV issue? Should I initialize the Mat
in a certain way?
If not, what string / pointer should I pass to the NDK so it can load the image?
Solution
Pass pointer
Java side:
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 side:
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());
}
Pass byte array
Java side:
public native String byteToJNI(byte[] myArray);
Native side:
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());
}
Answered By - orangesomethingorange
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.