so there is OpenCV for Java now...!
Can anyone tell me how to open Videofiles with it ?
I tryed and look all over the internet, but found nothing. The documentation of the VideoCapture class is not very helpfull, becaus it gives a C# example and show how to capture from a webcam.
the Q&A of OpenCV doesnt help either, because there is no (public) method to whom you can give a filename string.
BUT it should work as written in the API. But it doesn't
There is however a privte method in the VideoCapture class with a sting parameter.
please answer if have a solution, or even if you have the same problem.
garyee
UPDATE: (May 2017)
since Version 3.0.0 There is a constructor for the VideoCapture class that takes a string argument. So there is a easy solution to this Problem now!
解决方案
To me its a mystery why the so called automatically generated java wrapper for opencv is lacking this functionality. I first created a new VideoCapture class with a VideoCapture(String filename) constructor and called the private native method. This lead to an an unsatisfied link error:
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.(VideoCapture.java:90)
at Tester.main(Tester.java:30)
This indicates that the corresponding JNIEXPORT is missing.
Luckily this can be fixed.
Surprisingly the needed c-constructor is already defined in opencv-2.4.6/modules/highgui/include/opencv2/highgui/highgui.cpp
CV_WRAP VideoCapture(const string& filename);
We add the constructor we long to the VideoCapture class in opencv-2.4.6/modules/java/generator/src/java/highgui+VideoCapture.java:
//
// C++: VideoCapture::VideoCapture(const string& filename)
//
// javadoc: VideoCapture::VideoCapture(String filename)
public VideoCapture(String filename)
{
nativeObj = n_VideoCapture(filename);
return;
}
The crucial and tricky step was to add the jni export. Especially finding the right method name for the JNICALL proved to be challenging, since the constructor is overloaded and takes a java class as argument. Additionally we need to convert the java sting into a c-string. The rest is copied from the other constructors.
In opencv-2.4.6/modules/java/generator/src/cpp/VideoCapture.cpp we add this new 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 code {highgui::VideoCapture_n_1VideoCapture__Ljava_lang_String_2()}");
return 0;
}
}
Recompile OpenCV and it should work.