在我看来,为什么为opencv所谓的自动生成的Java包装器缺少此功能是一个谜。我首先用VideoCapture(String
filename)构造函数创建了一个新的VideoCapture类,并调用了私有本机方法。这导致不满意的链接错误:
Exception in thread "main" java.lang.UnsatisfiedlinkError: org.opencv.highgui.VideoCapture.n_VideoCapture(Ljava/lang/String;)J at org.opencv.highgui.VideoCapture.n_VideoCapture(Native Method) at org.opencv.highgui.VideoCapture.<init>(VideoCapture.java:90) at Tester.main(Tester.java:30)
这表明缺少相应的JNIEXPORT。幸运的是,这可以解决。
令人惊讶的是,所需的c构造函数已在 opencv-2.4.6 / modules / highgui / include / opencv2 /
highgui / highgui.cpp中定义
CV_WRAP VideoCapture(const string& filename);
我们在 opencv-2.4.6 / modules / java / generator / src / java / highgui +
VideoCapture.java中 的VideoCapture类中添加我们很久的构造函数 :
//// C++: VideoCapture::VideoCapture(const string& filename)//// javadoc: VideoCapture::VideoCapture(String filename)public VideoCapture(String filename){ nativeObj = n_VideoCapture(filename); return;}关键而棘手的步骤是添加jni导出。特别是,为JNICALL找到正确的方法名称被证明是具有挑战性的,因为构造函数已重载并且将Java类作为参数。另外,我们需要将java字符串转换为c字符串。其余的是从其他构造函数复制的。
在 opencv-2.4.6 / modules / java / generator / src / cpp /
VideoCapture.cpp中, 我们添加以下新的JNIEXPORT:
//// VideoCapture::VideoCapture(const string& filename)//JNIEXPORT jlong JNICALL Java_org_opencv_highgui_VideoCapture_n_1VideoCapture__Ljava_lang_String_2(JNIEnv* env, jclass, jstring filename);JNIEXPORT jlong JNICALL Java_org_opencv_highgui_VideoCapture_n_1VideoCapture__Ljava_lang_String_2(JNIEnv* env, jclass, jstring filename){ try { LOGD("highgui::VideoCapture_n_1VideoCapture__Ljava_lang_String_2()"); const char* jnamestr = env->GetStringUTFChars(filename, NULL); string stdFileName(jnamestr); VideoCapture* _retval_ = new VideoCapture( jnamestr ); return (jlong) _retval_; } catch(cv::Exception e) { LOGD("highgui::VideoCapture_n_1VideoCapture__Ljava_lang_String_2() catched cv::Exception: %s", e.what()); jclass je = env->FindClass("org/opencv/core/CvException"); if(!je) je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, e.what()); return 0; } catch (...) { LOGD("highgui::VideoCapture_n_1VideoCapture__Ljava_lang_String_2() catched unknown exception (...)"); jclass je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, "Unknown exception in JNI pre {highgui::VideoCapture_n_1VideoCapture__Ljava_lang_String_2()}"); return 0; }}重新编译OpenCV,它应该可以工作。



