You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中实现全局快门立体相机的指定帧率与分辨率视频录制?

如何在Rust中实现全局快门立体相机的指定帧率与分辨率视频录制?

看起来你遇到的核心问题是相机捕获格式不匹配——你的立体相机在3200x1200这类高分辨率下,只有MJPG(Motion-JPEG)压缩格式支持60fps的高帧率,而默认的YUYV raw格式在该分辨率下仅能达到2fps,这就是你用Rust OpenCV和初始ffmpeg命令时帧率暴跌的根本原因。下面我们一步步解决这个问题:

1. 先明确相机的支持参数

从你用v4l2-ctl --list-formats-ext -d 2的输出可以清晰看到:

  • MJPG格式:在3200x1200分辨率下支持60fps、30fps等多档帧率(对应Interval 0.017s即60fps)
  • YUYV格式:在3200x1200分辨率下仅支持2fps,这就是你之前代码和错误ffmpeg命令帧率极低的原因

所以不管是用Rust还是命令行,都必须强制指定使用MJPG格式来捕获视频。

2. 修复Rust OpenCV代码

你的原代码没有指定相机的捕获格式,默认使用了YUYV格式,导致高分辨率下帧率暴跌。我们需要在代码中强制设置相机使用MJPG格式,同时确认帧率和分辨率的设置对应相机支持的参数。

修改后的完整代码如下:

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

fn open_camera() -> Result<VideoCapture> {
    let capture = videoio::VideoCapture::new(2, videoio::CAP_ANY)?;
    // 强制设置捕获格式为MJPG
    capture.set(videoio::CAP_PROP_FOURCC, videoio::VideoWriter::fourcc('M', 'J', 'P', 'G')?)?;
    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 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)?;

    // 设置相机支持的帧率(MJPG格式3200x1200支持60fps)
    let fps = 60.0;
    cam.set(videoio::CAP_PROP_FPS, fps)?;

    // 初始化视频写入器,输出格式也使用MJPG保证录制速度
    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()? {
        eprintln!("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)?;

        // 按任意键退出,或捕获10秒(600帧)后自动退出
        let key = highgui::wait_key(1)?;
        if key > 0 || ctr >= 600 {
            break;
        }
        ctr += 1;
    }

    cam.release()?;
    writer.release()?;
    highgui::destroy_all_windows()?;
    Ok(())
}

关键修改点:

  • 在open_camera函数中,强制设置相机的捕获格式为MJPG,确保调用相机的高帧率模式
  • 确认帧率和分辨率严格对应相机支持的参数(60fps是MJPG格式3200x1200分辨率下的有效选项)

3. 命令行工具的参考验证(ffmpeg)

你已经找到正确的ffmpeg命令,这里再强调几个关键细节:

  • 参数顺序很重要:必须先指定-framerate 60,再指定输入格式和设备
  • 强制指定-input_format mjpeg,让ffmpeg调用相机的高帧率模式
  • 如果需要输出MKV格式且保持速度,建议分两步:先快速捕获原始MJPG流,再转码为高质量编码:
    # 第一步:快速捕获原始MJPG流,避免实时转码拖慢帧率
    ffmpeg -framerate 60 -f v4l2 -video_size 3200x1200 -input_format mjpeg -i /dev/video2 -c copy mjpeg_raw.mkv
    # 第二步:转码为高质量H.264编码的MKV
    ffmpeg -i mjpeg_raw.mkv -c:v libx264 -crf 23 -preset medium -pix_fmt yuv420p high_quality_out.mkv
    

4. 关于MJPG画质的小提示

MJPG是压缩格式,可能会让你觉得像素感较强,你可以:

  • 检查相机是否支持调整MJPG压缩率(部分相机可通过v4l2-ctl -d 2 --set-ctrl jpeg_quality=90这类命令调整,数值越高画质越好)
  • 转码时选择合适的画质参数(比如上述ffmpeg命令中的-crf 23,18-25是兼顾画质和体积的合理区间,数值越小画质越高)

备注:内容来源于stack exchange,提问作者El_Loco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:29:30