Jua*_*che 5 c++ java-native-interface opencv parameter-passing mat
我正在使用OpenCV和JNI开发一个Android项目.
其实我正在改变面部检测样本.
我遇到的问题是,当我传递一个cv :: Mat引用时,它会给出一些strane输出并且传递不好.
为了让你处于这种状况,我在我的FdActivity.java中有这个,这是我的Android应用程序的主要活动:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
rgb = inputFrame.rgba();
Mat res = mNativeDetector.process(rgb);
return res;
}
Run Code Online (Sandbox Code Playgroud)
过程函数是这样的:
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;
}
Run Code Online (Sandbox Code Playgroud)
其中nativeSkinFilter是具有此声明的本机函数
private static native Mat nativeSkinFilter(long thiz, long inputImage);
Run Code Online (Sandbox Code Playgroud)
在C++方面,我有函数声明(DetectionBasedTracker.h):
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jlong);
Run Code Online (Sandbox Code Playgroud)
我唯一想做的就是返回相同的图像,只需通过C++函数(一旦我知道我可以正确传递矩阵就会出现更复杂的实现),所以代码就像这样(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;
}
Run Code Online (Sandbox Code Playgroud)
我有的ouptut如下:
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
Run Code Online (Sandbox Code Playgroud)
我想我已经尝试了一切,但它似乎是正确的方式,它仍然失败.你能帮我吗?
非常感谢您的宝贵时间!帮助将非常感激.
这
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jlong);
Run Code Online (Sandbox Code Playgroud)
应该是这个
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jobject, jlong);
Run Code Online (Sandbox Code Playgroud)
因为在java中这样的调用
n = nativeSkinFilter(mNativeObj, rgb.getNativeObjAddr());
Run Code Online (Sandbox Code Playgroud)
需要 4 个参数:
在c++端,第二个参数后面就是你在java端传入的参数了。换句话说,在 C++ 端通过 Java->C++(无论是实例还是静态函数)进行的每次调用,前 2 个参数都是强制性的。然后是 Java 代码中“(”和“)”之间的参数。