meteor_detect/demos/file_input_demo.rs

115 lines
3.7 KiB
Rust

use std::path::PathBuf;
use std::io::{self, Write};
use chrono::{Local, Utc};
use anyhow::{Context, Result};
use opencv::{highgui, core, prelude::*};
use tokio;
use std::sync::{Arc, Mutex};
// 导入项目中的模块
use meteor_detect::camera::{CameraSettings, Resolution, ExposureMode, CameraController, Frame};
use meteor_detect::config::{Config, load_config};
use meteor_detect::overlay::star_chart::{StarChart, StarChartOptions};
use meteor_detect::gps::{GpsStatus, GeoPosition, CameraOrientation};
#[tokio::main]
async fn main() -> Result<()> {
println!("*** File Input Demo ***");
println!("This demo shows how to use a video file as input for the meteor detection system");
println!("It will apply the star chart overlay to the video frames");
println!("Press 'q' to quit");
println!();
// 读取视频文件路径
println!("Enter the path to a video file:");
let mut file_path = String::new();
io::stdin().read_line(&mut file_path)?;
let file_path = file_path.trim();
// 检查文件是否存在
if !std::path::Path::new(file_path).exists() {
println!("Error: File '{}' does not exist", file_path);
return Ok(());
}
// 创建配置
let mut config = load_config().unwrap();
// 设置为文件输入模式
config.camera.file_input_mode = true;
config.camera.input_file_path = file_path.to_string();
config.camera.loop_video = true;
// 确保星图配置已启用
config.star_chart.enabled = true;
// 初始化相机控制器
let mut camera_controller = CameraController::new(&config).await.unwrap();
println!("Initializing with video file: {}", file_path);
camera_controller.initialize().await.unwrap();
// 创建星图覆盖层
let gps_status = Arc::new(Mutex::new(GpsStatus::default()));
let mut star_chart = StarChart::new(
config.star_chart.clone(),
gps_status.clone()
).await.unwrap();
println!("Starting video playback...");
camera_controller.start_capture().await.unwrap();
// 获取帧订阅
let mut frame_rx = camera_controller.subscribe_to_frames();
// 创建窗口
highgui::named_window("File Input Demo", highgui::WINDOW_NORMAL)?;
highgui::resize_window("File Input Demo", 1280, 720)?;
// 处理帧循环
while let Ok(frame) = frame_rx.recv().await {
// 创建用于显示的帧
let mut display_frame = frame.mat.clone();
// 应用星图覆盖
if let Err(e) = star_chart.apply(&mut display_frame, frame.timestamp).await {
println!("Error applying star chart: {}", e);
}
// 在帧上显示时间戳和帧计数
let timestamp_text = format!("Frame: {} - Time: {}",
frame.index,
frame.timestamp.with_timezone(&Local).format("%Y-%m-%d %H:%M:%S%.3f")
);
opencv::imgproc::put_text(
&mut display_frame,
&timestamp_text,
core::Point::new(10, 30),
opencv::imgproc::FONT_HERSHEY_SIMPLEX,
1.0,
core::Scalar::new(0.0, 255.0, 0.0, 0.0),
2,
opencv::imgproc::LINE_AA,
false,
)?;
// 显示帧
highgui::imshow("File Input Demo", &display_frame)?;
// 检查按键
let key = highgui::wait_key(1)?;
if key == 'q' as i32 {
println!("Quitting...");
break;
}
}
// 清理
println!("Shutting down...");
camera_controller.stop_capture().await.unwrap();
highgui::destroy_all_windows()?;
println!("Demo completed successfully");
Ok(())
}