Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Reading a frame in OpenCV

i have just started to learn openCV in java and i have setup my Eclipse IDE with all OpenCV java dependencies.

Now i have a task in hand to extract a single frame from a video file which i have recorded in .avi file format.

i searched from this link and used the code given there as below,

package vasanth;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;

public class Vasanth {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    VideoCapture camera = new VideoCapture("G:\\PICTURES\\roxtar vassy\\early days in APSCE.wmv");



/*  if(!camera.isOpened()){
        System.out.println("Error");
    } */


        Mat frame = new Mat();  

        while(true){
            System.out.println("Looping.. \n");
            if (camera.read(frame)){
                System.out.println("Frame Obtained");
                System.out.println("Captured Frame Width " + 
                frame.width() + " Height " + frame.height());
                Highgui.imwrite("camera.jpg", frame);

                System.out.println("OK");
                break;
            }
        }   
    }

}

when i execute this, the program is looping at inifinitely at this line

camera.read(frame)

i also tried running this code without he loop and was successfully in getting the camera.jpg file on my system but the file was corrupted. I understand that this frame was not completely extracted with all the pixels and hence seems corrupted.

So the problem here is why does camera.read(frame) this always return false and the loop never breaks?

I have waited for more than 10 minutes. All i want to do is extract one single frame and it is not happening with this method.

As per what i have searched on google i understant there is a tool called ffmpeg which takes a video file as input and give me frames. But i want to achieve this functionality with my own java code running on Eclipse for starters.

like image 337
Vasanth Nag K V Avatar asked May 24 '26 15:05

Vasanth Nag K V


1 Answers

There are couple of issues I faced while reproducing your issue, so let me guide you through them.

  1. First of all, you use the old version of the framework. The current one is 3.2, so consider upgrading. I used the newest version.

  2. You should not comment out the camera.isOpened() check since if the camera is not opened there is no sense to proceed. I assume, that your app couldn't pass that check, so you decided to skip that :) But in order to open the camera properly you should either do this or this. The first link worked for me (the only change is that for 3.2 version the path is \opencv\build\x64\vc14\bin and I had to reboot computer)

The code is pretty much the same as you have so far with only difference for the latest version:

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;

import javax.swing.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.nio.file.Paths;

public class Vasanth {

    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        String filePath = "G:\\PICTURES\\roxtar vassy\\early days in APSCE.wmv";
        if (!Paths.get(filePath).toFile().exists()){
             System.out.println("File " + filePath + " does not exist!");
             return;
        }

        VideoCapture camera = new VideoCapture(filePath);

        if (!camera.isOpened()) {
            System.out.println("Error! Camera can't be opened!");
            return;
        }
        Mat frame = new Mat();

        while(true){
            if (camera.read(frame)){
                System.out.println("Frame Obtained");
                System.out.println("Captured Frame Width " +
                        frame.width() + " Height " + frame.height());
                Imgcodecs.imwrite("camera.jpg", frame);
                System.out.println("OK");
                break;
            }
        }

        BufferedImage bufferedImage = matToBufferedImage(frame);
        showWindow(bufferedImage);
        camera.release();
    }

    private static BufferedImage matToBufferedImage(Mat frame) {
        int type = 0;
        if (frame.channels() == 1) {
            type = BufferedImage.TYPE_BYTE_GRAY;
        } else if (frame.channels() == 3) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        BufferedImage image = new BufferedImage(frame.width(), frame.height(), type);
        WritableRaster raster = image.getRaster();
        DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
        byte[] data = dataBuffer.getData();
        frame.get(0, 0, data);

        return image;
    }

    private static void showWindow(BufferedImage img) {
        JFrame frame = new JFrame();
        frame.getContentPane().add(new JLabel(new ImageIcon(img)));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(img.getWidth(), img.getHeight() + 30);
        frame.setTitle("Image captured");
        frame.setVisible(true);
    }
}

Note, that in order to demonstrate that this piece of code works I use simple Swing JFrame:

enter image description here

like image 96
Enigo Avatar answered May 26 '26 04:05

Enigo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!