我购买了一台具有全局快门且帧速率最高为 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 来做。但其他解决方案也可以。
请原谅我的 C++,我不会说 Rust。
使用 OpenCV 和相机,总是一样的:将
CAP_PROP_FOURCC
设置为 VideoWriter::fourcc('M','J','P','G')
或 Rust 的等效代码。是的,这就是VideoCapture
。
您可以在构造函数中传递属性列表。之后无需调用
set()
方法。
人们报告说属性(或 set() 调用)的顺序很重要,因此首先和最后尝试 FOURCC 属性设置。至少其中之一会起作用。
始终使用 ffmpeg 和其他工具构建相机访问原型,这些工具可以为您提供所有可接受的视频模式的列表。
请注意,您的相机在 1600x600 的分辨率下只能达到 120 fps,而不是更高分辨率。 V4L 上限列表和产品页面都指出了这一点。