2013-07-07 228 views
4

我正在用OpenCV和JNI开发一个Android项目。在Android上使用OpenCV将cv :: Mat传递给JNI时出错

其实我正在改变面部检测样本。

我遇到的问题是,当我传递一个cv :: Mat引用时,它给出了一些输出,并且它不能很好地传递。

把你的情况,我有这个在我的FdActivity.java,这是我的Android应用程序的主要活动:

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

的处理功能是这样的:

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; 
} 

凡nativeSkinFilter是本声明的本地函数

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

在C++方面我有f结声明(DetectionBasedTracker.h):

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

我想要做的就是返回相同的图像,只由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; 
} 

的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 

我想我已经试过everythi ng,但它似乎是正确的方式,它仍然失败。 你能帮我吗?

非常感谢您的时间!帮助将非常感激。

回答

1

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

应该是这个

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

因为在Java

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

这样的调用需要4个参数:

  • JNEnv(显而易见)
  • jclass是类。或者,如果你是从一个实例调用该方法将是jobject
  • jobject为您传递一些对象
  • jlong​​现在这是实际的矩阵您正在寻找

在C++方面,在第二个参数之后,传递给你在Java端传入的参数。换句话说,在C++端通过Java-> C++调用每个调用(不管是实例还是静态函数),前两个参数都是必需的。然后在Java代码中跟随“(”和“)”之间的参数。

+0

是啊!那就对了。我前一段时间想到了,但我忘了发布解决方案。 非常感谢! :d –