Rust opencv crate摄像头严重卡顿问题排查与解决方案
Rust OpenCV调用摄像头帧率过低问题解决(Ubuntu 22.04)
环境信息
- Ubuntu 22.04 系统
- Rust 版本 1.76.0
- opencv crate 版本 0.88.8
- 已执行
apt install libopencv-dev clang libclang-dev完成依赖部署
问题现象
运行OpenCV官方示例代码调用摄像头时,功能正常但画面严重卡顿。摄像头原生支持22-24FPS,通过帧率测试代码测得实际帧率仅约8FPS;相同场景下的Python版OpenCV代码无任何卡顿。
初始卡顿的Rust代码
use opencv::{highgui, prelude::*, videoio, Result}; fn main() -> Result<()> { let window = "video capture"; highgui::named_window(window, highgui::WINDOW_AUTOSIZE)?; let mut cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?; // 0为默认摄像头 let opened = videoio::VideoCapture::is_opened(&cam)?; if !opened { panic!("无法打开默认摄像头!"); } loop { let mut frame = Mat::default(); cam.read(&mut frame)?; if frame.size()?.width > 0 { highgui::imshow(window, &frame)?; } let key = highgui::wait_key(10)?; if key > 0 && key != 255 { break; } } Ok(()) }
帧率测试代码片段
let fps_start = Instant::now(); let num_frames_to_measure = 60; for _ in 0..num_frames_to_measure { let mut temp_frame = Mat::default(); cam.read(&mut temp_frame)?; } let fps_duration = fps_start.elapsed(); let fps = num_frames_to_measure as f64 / fps_duration.as_secs_f64(); println!("实际帧率: {:?}", fps);
无卡顿的Python对比代码
import cv2 vid = cv2.VideoCapture(0) while True: ret, frame = vid.read() cv2.imshow('window', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break vid.release() cv2.destroyAllWindows()
解决方法
通过显式设置摄像头的宽高参数,可让摄像头工作在其支持的高帧率模式下,解决卡顿问题。修正后的完整代码如下:
修正后的Rust代码
use opencv::core::Vector; use opencv::{ highgui, prelude::*, videoio, imgcodecs }; use std::time::Instant; fn main() -> Result<(), Box<dyn std::error::Error>> { // 1. 初始化 let setup_start = Instant::now(); let mut cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?; // 0为默认摄像头 let opened = videoio::VideoCapture::is_opened(&cam)?; if !opened { println!("无法打开默认摄像头!"); return Ok(()); } cam.set(videoio::CAP_PROP_FRAME_WIDTH, 640.0)?; // 设置帧宽度 cam.set(videoio::CAP_PROP_FRAME_HEIGHT, 480.0)?; // 设置帧高度 let setup_duration = setup_start.elapsed().as_secs_f64(); // 计算初始化耗时 println!("初始化耗时: {:?}", setup_duration); // 打印初始化耗时 // 2. 测试帧率 let fps_start = Instant::now(); let num_frames_to_measure = 60; for _ in 0..num_frames_to_measure { let mut temp_frame = Mat::default(); cam.read(&mut temp_frame)?; } let fps_duration = fps_start.elapsed(); let fps = num_frames_to_measure as f64 / fps_duration.as_secs_f64(); println!("实际帧率: {:?}", fps); // 3. 显示摄像头画面 loop { let mut frame = Mat::default(); cam.read(&mut frame)?; if frame.size()?.width > 0 { highgui::imshow("camera", &frame)?; let key = highgui::wait_key(1)?; if key == 13 { // 按下回车键退出程序 break; } } } Ok(()) }
内容的提问来源于stack exchange,提问作者RedRum69
相关产品推荐
相关产品推荐

