()
| 7 | use std::time::Instant; |
| 8 | |
| 9 | fn main() -> Result<()> { |
| 10 | // 1. 打开摄像头 (索引 0) |
| 11 | // 底层会自动启动后台线程和 Tokio Runtime |
| 12 | println!("Opening camera..."); |
| 13 | let mut cap = VideoCapture::new(0)?; |
| 14 | |
| 15 | // 这一行会触发:停止流 -> 重置参数 -> 重新打开 -> 启动流 |
| 16 | println!("Setting resolution to 640x480..."); |
| 17 | if let Err(e) = cap.set_resolution(640, 480) { |
| 18 | eprintln!("Warning: Failed to set resolution: {}. Using default.", e); |
| 19 | } else { |
| 20 | println!("Resolution set successfully!"); |
| 21 | } |
| 22 | |
| 23 | if !cap.is_opened() { |
| 24 | eprintln!("Error: Could not open camera"); |
| 25 | return Ok(()); |
| 26 | } |
| 27 | |
| 28 | // 2. 预分配 Mat (为了 Buffer Swapping 优化) |
| 29 | // 实际上首次 read 会自动处理大小,这里创建一个空的即可 |
| 30 | let mut frame = Mat::empty(); |
| 31 | |
| 32 | let mut high_res_mode = false; |
| 33 | |
| 34 | // FPS 计算器 |
| 35 | let mut last_time = Instant::now(); |
| 36 | let mut frame_count = 0; |
| 37 | let mut fps = 0.0; |
| 38 | |
| 39 | println!("Start capturing... Press ESC or Q to exit."); |
| 40 | |
| 41 | // 3. 主循环 (经典的 OpenCV 风格) |
| 42 | while cap.read(&mut frame)? { |
| 43 | if frame.is_empty() { |
| 44 | continue; |
| 45 | } |
| 46 | |
| 47 | // --- 图像处理 (In-place 修改) --- |
| 48 | |
| 49 | // 模拟人脸检测框 (画一个静态的绿框) |
| 50 | let rect = imgproc::Rect::new(200, 150, 240, 240); |
| 51 | imgproc::rectangle( |
| 52 | &mut frame, |
| 53 | rect, |
| 54 | imgproc::Scalar::new(0, 255, 0), // Green (BGR) |
| 55 | 2, |
| 56 | ); |
| 57 | |
| 58 | // 计算 FPS |
| 59 | frame_count += 1; |
| 60 | if frame_count % 10 == 0 { |
| 61 | let now = Instant::now(); |
| 62 | let duration = now.duration_since(last_time).as_secs_f64(); |
| 63 | fps = 10.0 / duration; |
| 64 | last_time = now; |
| 65 | frame_count = 0; |
| 66 | } |
nothing calls this directly
no test coverage detected