UAV_odm_merge/utils/visualizer.py

120 lines
3.8 KiB
Python
Raw Normal View History

2024-12-30 17:34:21 +08:00
import os
import matplotlib.pyplot as plt
import pandas as pd
import logging
from typing import Optional
class FilterVisualizer:
"""过滤结果可视化器"""
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
def __init__(self, output_dir: str):
"""
初始化可视化器
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
Args:
output_dir: 输出目录路径
"""
self.output_dir = output_dir
self.logger = logging.getLogger('UAV_Preprocess.Visualizer')
2024-12-30 20:41:22 +08:00
def visualize_filter_step(self,
retained_points: pd.DataFrame,
filtered_points: pd.DataFrame,
step_name: str,
save_name: Optional[str] = None):
2024-12-30 17:34:21 +08:00
"""
可视化单个过滤步骤的结果
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
Args:
2024-12-30 20:41:22 +08:00
retained_points: 留下的点
filtered_points: 过滤掉的点
2024-12-30 17:34:21 +08:00
step_name: 步骤名称
save_name: 保存文件名默认为step_name
"""
2024-12-30 20:41:22 +08:00
total_points_len = len(retained_points) + len(filtered_points)
2024-12-30 17:34:21 +08:00
self.logger.info(f"开始生成{step_name}的可视化结果")
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 创建图形
plt.figure(figsize=(20, 16))
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 绘制保留的点
2024-12-30 20:41:22 +08:00
plt.scatter(retained_points['lon'], retained_points['lat'],
color='blue', label='Retained Points',
alpha=0.6, s=50)
2024-12-30 17:34:21 +08:00
# 绘制被过滤的点
if not filtered_points.empty:
plt.scatter(filtered_points['lon'], filtered_points['lat'],
2024-12-30 20:41:22 +08:00
color='red', marker='x', label='Filtered Points',
alpha=0.6, s=100)
2024-12-30 17:34:21 +08:00
# 设置图形属性
plt.title(f"GPS Points After {step_name}\n"
2024-12-30 20:41:22 +08:00
f"(Filtered: {len(filtered_points)}, Retained: {len(retained_points)})",
fontsize=14)
2024-12-30 17:34:21 +08:00
plt.xlabel("Longitude", fontsize=12)
plt.ylabel("Latitude", fontsize=12)
plt.grid(True)
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 添加统计信息
stats_text = (
2024-12-30 20:41:22 +08:00
f"Original Points: {total_points_len}\n"
2024-12-30 17:34:21 +08:00
f"Filtered Points: {len(filtered_points)}\n"
2024-12-30 20:41:22 +08:00
f"Remaining Points: {len(retained_points)}\n"
f"Filter Rate: {len(filtered_points)/total_points_len*100:.1f}%"
2024-12-30 17:34:21 +08:00
)
plt.figtext(0.02, 0.02, stats_text, fontsize=10,
2024-12-30 20:41:22 +08:00
bbox=dict(facecolor='white', alpha=0.8))
2024-12-30 17:34:21 +08:00
# 添加图例
plt.legend(loc='upper right', fontsize=10)
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 调整布局
plt.tight_layout()
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 保存图形
save_name = save_name or step_name.lower().replace(' ', '_')
2024-12-30 20:41:22 +08:00
save_path = os.path.join(
self.output_dir, 'filter_imgs_visual', f'filter_{save_name}.png')
2024-12-30 17:34:21 +08:00
plt.savefig(save_path, dpi=300, bbox_inches='tight')
plt.close()
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
self.logger.info(
f"{step_name}过滤可视化结果已保存至 {save_path}\n"
f"过滤掉 {len(filtered_points)} 个点,"
2024-12-30 20:41:22 +08:00
f"保留 {len(retained_points)} 个点,"
f"过滤率 {len(filtered_points)/total_points_len*100:.1f}%"
2024-12-30 17:34:21 +08:00
)
if __name__ == '__main__':
# 测试代码
import numpy as np
from datetime import datetime
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 创建测试数据
np.random.seed(42)
n_points = 1000
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 生成随机点
test_data = pd.DataFrame({
'lon': np.random.uniform(120, 121, n_points),
'lat': np.random.uniform(30, 31, n_points),
'file': [f'img_{i}.jpg' for i in range(n_points)],
'date': [datetime.now() for _ in range(n_points)]
})
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 随机选择点作为过滤后的结果
filtered_data = test_data.sample(n=800)
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
# 测试可视化
visualizer = FilterVisualizer('test_output')
os.makedirs('test_output', exist_ok=True)
2024-12-30 20:41:22 +08:00
2024-12-30 17:34:21 +08:00
visualizer.visualize_filter_step(
filtered_data,
test_data,
"Test Filter"
2024-12-30 20:41:22 +08:00
)