use anyhow::Result; use log::{error, info}; use std::path::PathBuf; use std::time::Duration; use tokio::time; // 导入Camera模块组件 use meteor_detect::camera::{CameraController, CameraSettings, ExposureMode, Resolution, Frame}; use meteor_detect::config::Config; /// 这是一个简单的演示程序,展示如何使用Camera模块的主要功能 #[tokio::main] async fn main() -> Result<()> { // 初始化日志 env_logger::init(); // 1. 创建配置 let config = create_demo_config(); // 2. 初始化相机控制器 info!("初始化相机控制器"); let mut camera_controller = CameraController::new(&config).await?; // 3. 初始化相机设备 info!("初始化相机设备"); camera_controller.initialize().await?; // 4. 启动视频捕获 info!("启动视频捕获"); camera_controller.start_capture().await?; // 5. 获取相机状态 let status = camera_controller.get_status().await?; info!("相机状态: {}", status); // 6. 订阅帧更新 info!("设置帧处理器"); let mut frame_receiver = camera_controller.subscribe_to_frames(); // 在单独的任务中处理帧 let frame_processor = tokio::spawn(async move { let mut frame_count = 0; // 处理10个帧后退出 while let Ok(frame) = frame_receiver.recv().await { frame_count += 1; info!("收到帧 #{}: 时间戳={}", frame.index, frame.timestamp); // 示例: 保存第5帧为图像文件 if frame_count == 5 { info!("保存第5帧为图像文件"); let path = PathBuf::from("demo_frame.jpg"); if let Err(e) = frame.save_to_file(&path) { error!("保存帧失败: {}", e); } } if frame_count >= 10 { info!("已处理10帧,退出处理循环"); break; } } info!("帧处理器已完成"); frame_count }); // 7. 等待5秒,然后模拟一个流星事件 info!("等待5秒后模拟流星事件..."); time::sleep(Duration::from_secs(5)).await; // 获取当前时间作为事件时间戳 let event_timestamp = chrono::Utc::now(); // 模拟流星事件检测 - 保存事件视频 info!("保存流星事件"); match camera_controller .save_meteor_event( event_timestamp, 0.85, // 置信度 (100, 100, 200, 150), // 边界框 (x, y, width, height) 3, // 事件前3秒 2, // 事件后2秒 ) .await { Ok(event) => { info!("保存了流星事件: id={}, 视频='{}'", event.id, event.video_path); } Err(e) => { error!("保存流星事件失败: {}", e); } } // 8. 更新相机设置 info!("更新相机设置"); let mut new_settings = config.camera.clone(); new_settings.resolution = Resolution::HD1080p; new_settings.fps = 24; camera_controller.update_settings(new_settings).await?; // 9. 检查相机健康状态 info!("检查相机健康状态"); let is_healthy = camera_controller.check_health().await?; info!("相机健康状态: {}", if is_healthy { "正常" } else { "异常" }); // 10. 等待帧处理完成 info!("等待帧处理器完成"); let processed_frames = frame_processor.await?; info!("共处理了 {} 帧", processed_frames); // 11. 停止视频捕获 info!("停止视频捕获"); camera_controller.stop_capture().await?; info!("演示完成"); Ok(()) } /// 创建用于演示的配置 fn create_demo_config() -> Config { let camera_settings = CameraSettings { // 在Linux上通常是"/dev/video0",在macOS上通常是"0" device: "0".to_string(), resolution: Resolution::HD720p, fps: 30, exposure: ExposureMode::Auto, gain: 128, focus_locked: true, }; Config { camera: camera_settings, // 其他配置字段,使用其默认值 ..Default::default() } } // // /// 如果需要,这里提供一个更复杂的帧处理示例 // /// 可以作为单独函数供参考 // #[allow(dead_code)] // async fn process_frames_with_opencv(frame: &Frame) -> Result<()> { // use opencv::{core, imgproc, prelude::*}; // // // 1. 转换为灰度图像 // let mut gray = core::Mat::default(); // imgproc::cvt_color(&frame.mat, &mut gray, imgproc::COLOR_BGR2GRAY, 0)?; // // // 2. 应用高斯模糊 // let mut blurred = core::Mat::default(); // imgproc::gaussian_blur( // &gray, // &mut blurred, // core::Size::new(5, 5), // 1.5, // 1.5, // core::BORDER_DEFAULT, // )?; // // // 3. 应用边缘检测 // let mut edges = core::Mat::default(); // imgproc::canny(&blurred, &mut edges, 50.0, 150.0, 3, false)?; // // // 保存处理后的图像(可选) // opencv::imgcodecs::imwrite("processed_frame.jpg", &edges, &core::Vector::new())?; // // Ok(()) // }