open video file with opencv java

前端 未结 4 801
北荒
北荒 2020-12-31 22:29

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

相关标签:
4条回答
  • 2020-12-31 22:56

    here is an example :

        public static void main(String[] args) {
        Mat frame = new Mat();
        VideoCapture camera = new VideoCapture("C:/Users/SAAD/Desktop/motion.mp4");
        JFrame jframe = new JFrame("Title");
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel vidpanel = new JLabel();
        jframe.setContentPane(vidpanel);
        jframe.setVisible(true);
    
        while (true) {
            if (camera.read(frame)) {
    
                ImageIcon image = new ImageIcon(Mat2bufferedImage(frame));
                vidpanel.setIcon(image);
                vidpanel.repaint();
    
            }
        }
    }`
    

    if you are using Windows add C:\opencv\build\x86\vc11\bin to the Path variable

    0 讨论(0)
  • 2020-12-31 23:04

    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.<init>(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.

    0 讨论(0)
  • 2020-12-31 23:06

    If you are using the new version of Java, this is how I got it to work.

    import org.opencv.core.*;
    import org.opencv.videoio.*;
    
    import java.awt.image.BufferedImage;
    import java.awt.image.DataBufferByte;
    
    import javax.swing.*;public class MainStruct {
    
    public class MainStruct {
    
    static { 
        try {
        System.load("C:opencv\\build\\x64\\vc14\\bin\\opencv_ffmpeg320_64.dll");
        } catch (UnsatisfiedLinkError e) {
            System.err.println("Native code library failed to load.\n" + e);
            System.exit(1);
        }
    }
    
    public static void main(String[] args)
    {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    
        //Create new MAT object
        Mat frame = new Mat();
    
        //Create new VideoCapture object
        VideoCapture camera = new VideoCapture("C:\\**VideoFileLocation**");
    
        //Create new JFrame object
        JFrame jframe = new JFrame("Video Title);
    
        //Inform jframe what to do in the event that you close the program
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        //Create a new JLabel object vidpanel
        JLabel vidPanel = new JLabel();
    
        //assign vidPanel to jframe
        jframe.setContentPane(vidPanel);
    
        //set frame size
        jframe.setSize(2000, 4000);
    
        //make jframe visible
        jframe.setVisible(true);
    
        while (true) {
            //If next video frame is available
            if (camera.read(frame)) {
                //Create new image icon object and convert Mat to Buffered Image
                ImageIcon image = new ImageIcon(Mat2BufferedImage(frame));
                //Update the image in the vidPanel
                vidPanel.setIcon(image);
                //Update the vidPanel in the JFrame
                vidPanel.repaint();
    
            }
        }
    }
    
    public static BufferedImage Mat2BufferedImage(Mat m) {
        //Method converts a Mat to a Buffered Image
        int type = BufferedImage.TYPE_BYTE_GRAY;
         if ( m.channels() > 1 ) {
             type = BufferedImage.TYPE_3BYTE_BGR;
         }
         int bufferSize = m.channels()*m.cols()*m.rows();
         byte [] b = new byte[bufferSize];
         m.get(0,0,b); // get all the pixels
         BufferedImage image = new BufferedImage(m.cols(),m.rows(), type);
         final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
         System.arraycopy(b, 0, targetPixels, 0, b.length);  
         return image;
        }
    

    }

    0 讨论(0)
  • 2020-12-31 23:08

    Here is how it worked for me.

    VideoCapture capture=new VideoCapture();
    capture.open("Vid.mp4");
    Mat frame=new Mat();
                
       
    for(;;){
       capture.read(frame); //reads captured frame into the Mat image
       imshow("Display",frame);
       if(cvWaitKey(30) >= 0) break;
    }

    0 讨论(0)
提交回复
热议问题