Java - 在OpenCV中读取一个框架

时间:2017-02-26 09:08:03

标签: java eclipse opencv

我刚刚开始在java中学习openCV,我已经设置了我的Eclipse IDE以及所有OpenCV java依赖项。

现在我手头有一项任务从我以.avi文件格式录制的视频文件中提取单帧。

我从这个link搜索并使用下面给出的代码,

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

}

当我执行此操作时,程序在此行无限循环

camera.read(frame)

我也尝试在没有循环的情况下运行此代码,并成功获取了我的系统上的camera.jpg文件,但该文件已损坏。 据我所知,这个框架没有完全用所有像素提取,因此看起来已经损坏了。

所以这里的问题是为什么camera.read(frame)总是返回false而循环永远不会中断?

我等了10多分钟。 我想要做的就是提取一个单独的帧,这种方法不会发生。

根据我在google上搜索的内容,我知道有一个名为ffmpeg的工具,它将视频文件作为输入并给我帧。 但是我希望用我在Eclipse上运行的java代码为启动器实现这个功能。

2 个答案:

答案 0 :(得分:0)

在复制你的问题时我遇到了几个问题,所以让我引导你完成它们。

  1. 首先,您使用旧版本的框架。目前的是3.2,所以考虑升级。我使用的是最新版本。

  2. 你不应该注释camera.isOpened()检查,因为如果没有打开相机,就没有意义继续。我认为,你的应用无法通过该检查,所以你决定跳过那个:)但是为了正确打开相机你应该thisthis。第一个链接适用于我(唯一的变化是3.2版本的路径是\opencv\build\x64\vc14\bin,我不得不重新启动计算机)

  3. 代码与目前几乎完全相同,只是最新版本的差异:

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

    注意,为了证明这段代码有用,我使用简单的Swing JFrame:

    enter image description here

答案 1 :(得分:0)

我面临着同一问题,即camera.isOpened()返回false。 这就是我解决的方法。

String filePath = "C:\\Aslam_Face_Detection.mp4";
VideoCapture camera = new VideoCapture(filePath);
camera.open(filePath); // This is the line I added
camera.isOpened(); // returns true. worked.