java - 用opencv java打开视频文件

标签 java file opencv video

因此 Java now... 有 OpenCV ! 谁能告诉我如何用它打开视频文件?

我试着在网上找遍了,但一无所获。 VideoCapture 类的文档不是很有帮助,因为它提供了一个 C# 示例并展示了如何从网络摄像头进行捕获。

Q&A of OpenCV也无济于事,因为没有(公共(public))方法可以向其提供文件名字符串。

但它应该按照 API 中的规定工作。但事实并非如此 然而,在 VideoCapture 类中有一个带有 sting 参数的私有(private)方法。

请回答是否有解决方案,或者即使您有同样的问题。 加里伊

更新:(2017 年 5 月)

从版本 3.0.0 开始 VideoCapture 类有一个构造函数,它接受一个字符串参数。所以现在有一个简单的解决方案来解决这个问题!

最佳答案

对我来说,为什么所谓的自动生成的 opencv java 包装器缺少此功能是个谜。我首先使用 VideoCapture(String filename) 构造函数创建了一个新的 VideoCapture 类,并调用了私有(private) native 方法。这会导致不满意的链接错误:

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 code {highgui::VideoCapture_n_1VideoCapture__Ljava_lang_String_2()}");
        return 0;
    }
}

重新编译 OpenCV,它应该可以工作。

关于java - 用opencv java打开视频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17401852/

相关文章:

PHP is_file 和服务器根相对路径

c++ - 我在 Mac OS X 上的 .dylib 文件在哪里?

java - 使用 kit.insertHTML() 更新时,jTextPane 中的第一个单词消失

java - Selenium - 运行 ChromeDriver 而不修改路径

java - 使用java将一组字符转换为不同的字符串数组

python - 如何在python中找到每个SLIC超像素的质心?

c++ - 使用Opencv提取图像的公共(public)部分

java - Hadoop jvm 进程挂起,没有任何错误消息,

java - 处理不可访问的异常类型

java - Android Java -- 在Android平台反序列化一个文件