在 Rust 中录制视频流

问题描述 投票:0回答:1

我购买了一台具有全局快门且帧速率最高为 120 fps 的立体相机。 https://www.amazon.com/dp/B0D8T3ZSL4?ref_=pe_386300_442618370_TE_sc_as_ri_0#

我的下一步是编写一个程序,可以以所需的 fps 和分辨率显示和录制视频。

use opencv::{
    core, highgui,
    prelude::*,
    videoio::{self, VideoCapture},
    Result,
};

fn open_camera() -> Result<VideoCapture> {
    let capture = videoio::VideoCapture::new(2, videoio::CAP_ANY)?;
    return Ok(capture);
}
fn main() -> Result<()> {
    let window = "video capture";
    highgui::named_window(window, highgui::WINDOW_AUTOSIZE)?;
    let mut cam = open_camera()?;
    let opened = videoio::VideoCapture::is_opened(&cam)?;
    if !opened {
        panic!("Unable to open default camera!");
    }
    let width = 3200.0;
    let height = 1200.0;
    cam.set(videoio::CAP_PROP_FRAME_WIDTH, width)?;
    cam.set(videoio::CAP_PROP_FRAME_HEIGHT, height)?;

    // Set the frame rate (FPS)
    let fps = 60.0;
        
    let fourcc = videoio::VideoWriter::fourcc('M', 'J', 'P', 'G')?;
    let mut writer = videoio::VideoWriter::new(
        "video_output.avi",
        fourcc,
        fps,
        core::Size::new(width as i32, height as i32),
        true,
    )?;

    if !writer.is_opened()? {
        println!("Error: Could not open the video writer.");
    }

    let mut frame = core::Mat::default();
    let mut ctr = 0;
    while cam.read(&mut frame)? {
        if frame.empty() {
            break;
        }
        writer.write(&frame)?;
        highgui::imshow(window, &frame)?;
        
        let key = highgui::wait_key(1)?;
        if key > 0 {
            break;
        }
        ctr += 1;
        if ctr == 600 {
            break;
        }
    }
    cam.release()?;
    writer.release()?;
    Ok(())
}

当我运行此代码时,帧速率非常糟糕。比如 1 fps 之类的。为了调试,我尝试在奶酪中运行。我得到了全分辨率 30 fps

3200x1200
。但我无法将 fps 更改为我所看到的 60 fps。

然后我尝试使用 ffmpeg 捕获视频:

 ffmpeg -f v4l2 -framerate 60 -video_size 3200x1200 -i /dev/video2 output.mp4

输出如下:

[video4linux2,v4l2 @ 0x5a72cbbd1400] The driver changed the time per frame from 1/60 to 1/2
Input #0, video4linux2,v4l2, from '/dev/video2':
  Duration: N/A, start: 2744.250608, bitrate: 122880 kb/s
  Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 3200x1200, 122880 kb/s, 2 fps, 2 tbr, 1000k tbn
File 'output.mp4' already exists. Overwrite? [y/N]

帧速率降低至 2 fps。

然后我尝试运行

v4l2-ctl --list-formats-ext -d 2
,输出如下:

ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture

        [0]: 'MJPG' (Motion-JPEG, compressed)
                Size: Discrete 3200x1200
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.100s (10.000 fps)
                Size: Discrete 2560x720
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.100s (10.000 fps)
                Size: Discrete 1600x600
                        Interval: Discrete 0.008s (120.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)

然后我尝试使用

qv4l
打开相机,它似乎可以工作。不过好像我不能录制视频。

我正在使用 Rust 来学习。我希望能够以编程方式录制视频,然后进行计算机视觉。最简单的方法是用 Rust 来做。但其他解决方案也可以。

opencv rust ffmpeg v4l2 uv4l
1个回答
0
投票

请原谅我的 C++,我不会说 Rust。

使用 OpenCV 和相机,总是一样的:将

CAP_PROP_FOURCC
设置为
VideoWriter::fourcc('M','J','P','G')
或 Rust 的等效代码。是的,这就是
VideoCapture

您可以在构造函数中传递属性列表。之后无需调用

set()
方法。

人们报告说属性(或 set() 调用)的顺序很重要,因此首先和最后尝试 FOURCC 属性设置。至少其中之一会起作用。


始终使用 ffmpeg 和其他工具构建相机访问原型,这些工具可以为您提供所有可接受的视频模式的列表。

请注意,您的相机在 1600x600 的分辨率下只能达到 120 fps,而不是更高分辨率。 V4L 上限列表和产品页面都指出了这一点。

© www.soinside.com 2019 - 2024. All rights reserved.