简体   繁体   English

如何从 Java 中的视频中提取所有帧?

[英]How do I extract all the frames from a video in Java?

I'm trying to grab the frames from a video and put them into a collection of BufferedImage so I can use the images later.我正在尝试从视频中抓取帧并将它们放入 BufferedImage 集合中,以便稍后使用这些图像。 I tried to use the code in the second answer for this question, but it wasn't really helpful because the code they provided only grabs the first frame.我尝试使用这个问题的第二个答案中的代码,但这并不是很有帮助,因为他们提供的代码只抓取了第一帧。 How would I extract all the frames and put them into a collection?我将如何提取所有帧并将它们放入集合中?

So, a little bit of Googling (and reading the source code), was I able to hobble together this basic concept.因此,通过一些谷歌搜索(并阅读源代码),我是否能够将这个基本概念拼凑在一起。

The "obvious" solution was to loop over the frames in the video and extract them, the "un-obvious" solution was "how"?! “明显”的解决方案是循环播放视频中的帧并提取它们,“不明显”的解决方案是“如何”?!

The two methods you need are FFmpegFrameGrabber#getLengthInFrames and FFmpegFrameGrabber#setFrameNumber , from there it's just a simple method of converting the current frame and writing it to a file (which has already been demonstrated from the previous question)您需要的两种方法是FFmpegFrameGrabber#getLengthInFramesFFmpegFrameGrabber#setFrameNumber ,从那里它只是一种转换当前帧并将其写入文件的简单方法(已经在上一个问题中进行了演示)

File videoFile = new File("Storm - 106630.mp4");
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videoFile.getAbsoluteFile());
frameGrabber.start();
Java2DFrameConverter c = new Java2DFrameConverter();
int frameCount = frameGrabber.getLengthInFrames();
for (int frameNumber = 0; frameNumber < frameCount; frameNumber++) {
    System.out.println("Extracting " + String.format("%04d", frameNumber) + " of " + String.format("%04d", frameCount) + " frames");
    frameGrabber.setFrameNumber(frameNumber);
    Frame f = frameGrabber.grab();
    BufferedImage bi = c.convert(f);
    ImageIO.write(bi, "png", new File("Frame " + String.format("%04d", frameNumber) + "-" + String.format("%04d", frameCount) + ".png"));
}
frameGrabber.stop();

Now, obviously, you could store the images into some kind of List in memory, just beware, depending on the size and length of the original video, this might run you into memory issues.现在,显然,您可以将图像存储到内存中的某种List中,请注意,根据原始视频的大小和长度,这可能会使您遇到内存问题。

You can use OpenCV to extract frames in a video, try the below code.您可以使用 OpenCV 提取视频中的帧,试试下面的代码。 input is the video file path of your computer input是你电脑的视频文件路径

 VideoCapture cap = new VideoCapture();

    String output = "resources/output";

    cap.open(input);

    int video_length = (int) cap.get(Videoio.CAP_PROP_FRAME_COUNT);
    int frames_per_second = (int) cap.get(Videoio.CAP_PROP_FPS);

    Mat frame = new Mat();

    if (cap.isOpened()) {

        System.out.println("Video is opened");
        System.out.println("Number of Frames: " + video_length);
        System.out.println(frames_per_second + " Frames per Second");

        System.out.println("Converting Video to images...");

        cap.read(frame);

        int frame_number = 0;

        while (cap.read(frame)) {
            Imgcodecs.imwrite(output + "/" + frame_number + ".jpg", frame);
            frame_number++;
        }

        cap.release();

        processingStatus = video_length + " Frames extracted";
        System.out.println(processingStatus);

    } else {
        processingStatus = "Failed";
        System.out.println(processingStatus);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM