Open video file with opencv java

so there is OpenCV for Java now ... ! Can someone tell me how to open video files with him?

I tried and looked all over the Internet, but found nothing. The documentation for the VideoCapture class is not very useful because it gives a C # example and shows how to capture from a webcam.

Q & A OpenCV does not help, because there is no (public) method to which you can specify a file name string.

BUT this should work as written in the API. But this is not. However, the VideoCapture class has a privacy parameter with the sting parameter.

answer if you have a solution, or even if you have the same problem. garyee

UPDATE: (May 2017)

starting with version 3.0.0. There is a constructor for the VideoCapture class that takes a string argument. So now there is an easy solution to this problem!

+4
source share
4 answers

The mysterious reason for me is why the so-called automatically generated Java shell for opencv does not have this functionality. First, I created a new VideoCapture class with the VideoCapture constructor (String filename) and called a private native method. This results in 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 means that the corresponding JNIEXPORT is missing. Fortunately, this can be fixed.

Surprisingly, the required 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 a constructor, which we have been adding for a long time 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 key and difficult step was to add jni export. Especially finding the right method name for JNICALL proved to be difficult because the constructor is overloaded and takes the java class as an argument. In addition, we need to convert java sting to c-string. The rest is copied from 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.

+5
source

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 use Windows add C: \ opencv \ build \ x86 \ vc11 \ bin to the Path variable

+1
source

Here's 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; } 
+1
source

If you are using a new version of Java, here's how I made it.

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

}

+1
source

Source: https://habr.com/ru/post/1489062/


All Articles