Java-在OpenCV中读取帧

Java-在OpenCV中读取帧,java,eclipse,opencv,Java,Eclipse,Opencv,我刚刚开始学习java中的openCV,我已经用所有openCV java依赖项设置了Eclipse IDE 现在我手头有一项任务,就是从我以.avi文件格式录制的视频文件中提取一帧 我从这里搜索并使用下面给出的代码 package vasanth; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.highgui.Highgui; import org.opencv.highgui.Video

我刚刚开始学习java中的openCV,我已经用所有openCV java依赖项设置了Eclipse IDE

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

我从这里搜索并使用下面给出的代码

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)
我还尝试在没有he循环的情况下运行此代码,并成功地在我的系统上获取camera.jpg文件,但该文件已损坏。 据我所知,这帧并没有完全提取所有的像素,因此似乎已损坏

所以这里的问题是为什么camera.read(frame)总是返回false,循环从不中断

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

根据我在谷歌上的搜索,我知道有一个叫做ffmpeg的工具,它把一个视频文件作为输入,给我帧。
但是我想用我自己在Eclipse上运行的java代码来实现这个功能,作为初学者。

在再现您的问题时,我遇到了几个问题,所以让我来指导您解决这些问题

  • 首先,使用旧版本的框架。当前一个是3.2,所以考虑升级。我用的是最新的版本

  • 您不应注释掉
    camera.isOpened()
    检查,因为如果未打开摄影机,则没有继续的意义。我认为,你的应用程序无法通过该检查,因此你决定跳过该检查:)但为了正确打开相机,你应该这样做或这样做。第一个链接对我有效(唯一的变化是3.2版本的路径是
    \opencv\build\x64\vc14\bin
    ,我必须重新启动计算机)

  • 代码与目前为止的代码基本相同,只是最新版本的代码有所不同:

    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:


    我面临着同样的问题,那就是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.
    

    感谢您在这个Enigo上花费的时间,所以您是说让它工作的唯一改变是版本升级和本机opencv libs的路径?还有,你花了多少时间才拍下这张照片?@VasanthNagKV,没错!老实说,我认为,如果你添加的所有内容都正确的话,即使对于你正在使用的版本,它也应该可以工作。我用非常短的视频(5秒长)进行了测试,图像立即被捕获。你觉得捕获单个帧所需的时间取决于整个视频长度吗?嗯,我不确定,但我认为不应该。因为,根据文档,这种方法只读取下一帧,所以帧的总大小应该无关紧要。不幸的是,我没有任何长视频来测试它。我尝试在我的机器上运行你的代码,我看到它卡在你在回答中评论的点上,如果(!camera.isOpened()){System.out.println(“错误!camera无法打开!”);return;}这是为什么??我查看了你提供的链接,但我不明白