Error transferring cv :: Mat to JNI using OpenCV on Android

I am developing an Android project with OpenCV and JNI.

In fact, I am changing the face detection image.

The problem is that when I pass the cv :: Mat link, it gives some strict output and is not passed properly.

To put you in a situation, I have this in my FdActivity.java, which is the main activity of my Android application:

public Mat onCameraFrame(CvCameraViewFrame inputFrame) { rgb = inputFrame.rgba(); Mat res = mNativeDetector.process(rgb); return res; } 

The function of the process is as follows:

 public Mat process(Mat rgb) { Mat n = null; if(rgb.empty()) { System.out.println("Empty Image"); } else { System.out.println("The image is " + rgb.rows() + "x" + rgb.cols()); n = nativeSkinFilter(mNativeObj, rgb.getNativeObjAddr()); } return n; } 

Where nativeSkinFilter is a native function with this declaration

 private static native Mat nativeSkinFilter(long thiz, long inputImage); 

On the C ++ side, I have a function declaration (DetectionBasedTracker.h):

 JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jlong); 

The only thing I want to do is return the same image by simply passing the C ++ function (a more complex implementation will come as soon as I find out that I can pass the matrix correctly), so the code is the same (DetectionBasedTracker.cpp):

 JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv * jenv,jclass,jlong rgb) { Mat* rgba = (Mat*) rgb; if(rgb == 0) { LOGD("Null matrix"); } else { LOGD("The matrix is not null. It has %i rows and %i columns", (*rgba).rows, (*rgba).cols); } return (jlong)rgb; } 

I have the following:

 07-07 13:00:07.671: I/Choreographer(14980): Skipped 55 frames! The application may be doing too much work on its main thread. 07-07 13:00:07.701: E/BufferQueue(14980): [unnamed-14980-0] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=6 undequeudCount=0) 07-07 13:00:07.741: I/JavaCameraView(14980): Preview Frame received. Need to create MAT and deliver it to clients 07-07 13:00:07.741: I/JavaCameraView(14980): Frame size is 576000 07-07 13:00:07.761: I/System.out(14980): The image is 480x800 07-07 13:00:07.761: D/FaceDetection/DetectionBasedTracker(14980): The matrix is not null. It has 1937716000 rows and 0 columns 07-07 13:00:07.761: E/cv::error()(14980): OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols) in void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean), file /home/reports/ci/slave_desktop/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp, line 97 07-07 13:00:07.761: E/org.opencv.android.Utils(14980): nMatToBitmap catched cv::Exception: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean) 07-07 13:00:07.761: A/libc(14980): Fatal signal 11 (SIGSEGV) at 0x0000000a (code=1), thread 15115 (Thread-5379) 07-07 13:00:07.791: E/BufferQueue(14980): [unnamed-14980-0] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=5 undequeudCount=1) 07-07 13:00:07.801: I/JavaCameraView(14980): Preview Frame received. Need to create MAT and deliver it to clients 07-07 13:00:07.801: I/JavaCameraView(14980): Frame size is 576000 

I think I tried everything, but it seems to be correct, and it still fails. Could you help me?

Thanks so much for your time! Help will be really appreciated.

+4
source share
1 answer

this is

 JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jlong); 

must be specified

 JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jobject, jlong); 

because a call like this in java

 n = nativeSkinFilter(mNativeObj, rgb.getNativeObjAddr()); 

expects 4 parameters:

  • JNEnv (obviously)
  • jclass is a class. Or, if you call a method from an instance, it will be jobject
  • jobject when passing an object
  • jlong ​​is now the actual matrix you are looking for

on the C ++ side, after the second parameter, the parameters that you pass on the Java side are passed. In other words, every call through Java-> C ++ (whether it be an instance or a static function) on the C ++ side is required. Then comes your options between "(" and ")" in the Java code.

+1
source

Source: https://habr.com/ru/post/1490121/


All Articles