115 lines
3.7 KiB
Rust
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,
|
|
×tamp_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(())
|
|
}
|