From 989648fcae6024beb858027cd5dda1dbddbd844e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E6=BE=B3?= Date: Sun, 22 Dec 2024 19:01:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8C=89=E7=85=A7=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E7=BB=84=E7=9A=84=E5=8F=AF=E8=A7=86=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logs/preprocess_20241222_185805.log | 3 + logs/preprocess_20241222_185926.log | 3 + odm_preprocess.py | 4 +- tools/show_GPS.py | 2 +- tools/show_GPS_by_time.py | 138 ++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 logs/preprocess_20241222_185805.log create mode 100644 logs/preprocess_20241222_185926.log create mode 100644 tools/show_GPS_by_time.py diff --git a/logs/preprocess_20241222_185805.log b/logs/preprocess_20241222_185805.log new file mode 100644 index 0000000..c246005 --- /dev/null +++ b/logs/preprocess_20241222_185805.log @@ -0,0 +1,3 @@ +2024-12-22 18:58:05 - UAV_Preprocess.GPSExtractor - INFO - 开始从目录提取GPS坐标和拍摄日期: F:\error_data\20241104140457\code\images +2024-12-22 18:58:22 - UAV_Preprocess.GPSExtractor - INFO - GPS坐标和拍摄日期提取完成 - 总图片数: 2708, 成功提取: 2708, 失败: 0 +2024-12-22 18:58:22 - UAV_Preprocess.GPSVisualizer - INFO - 已生成包含 14 个时间组的组合可视化图形 diff --git a/logs/preprocess_20241222_185926.log b/logs/preprocess_20241222_185926.log new file mode 100644 index 0000000..07b72cf --- /dev/null +++ b/logs/preprocess_20241222_185926.log @@ -0,0 +1,3 @@ +2024-12-22 18:59:26 - UAV_Preprocess.GPSExtractor - INFO - 开始从目录提取GPS坐标和拍摄日期: F:\error_data\20241108134711\3D +2024-12-22 19:00:09 - UAV_Preprocess.GPSExtractor - INFO - GPS坐标和拍摄日期提取完成 - 总图片数: 6615, 成功提取: 6615, 失败: 0 +2024-12-22 19:00:10 - UAV_Preprocess.GPSVisualizer - INFO - 已生成包含 8 个时间组的组合可视化图形 diff --git a/odm_preprocess.py b/odm_preprocess.py index 9513441..310c941 100644 --- a/odm_preprocess.py +++ b/odm_preprocess.py @@ -218,8 +218,8 @@ class ImagePreprocessor: if __name__ == "__main__": # 创建配置 config = PreprocessConfig( - image_dir=r"E:\datasets\UAV\502\project\images", - output_dir=r"E:\studio2\ODM_pro\test", + image_dir=r"F:\error_data\20240930091614\project\images", + output_dir=r"F:\error_data\20240930091614\output", cluster_eps=0.01, cluster_min_samples=5, diff --git a/tools/show_GPS.py b/tools/show_GPS.py index e486b90..f4690a6 100644 --- a/tools/show_GPS.py +++ b/tools/show_GPS.py @@ -5,7 +5,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import matplotlib.pyplot as plt from preprocess.gps_extractor import GPSExtractor -DATASET = r'E:\datasets\UAV\502\project\images' +DATASET = r'F:\error_data\20240930091614\project\images' if __name__ == '__main__': extractor = GPSExtractor(DATASET) diff --git a/tools/show_GPS_by_time.py b/tools/show_GPS_by_time.py new file mode 100644 index 0000000..f771275 --- /dev/null +++ b/tools/show_GPS_by_time.py @@ -0,0 +1,138 @@ +import os +import sys +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +import matplotlib.pyplot as plt +from datetime import timedelta +import logging +import numpy as np +from preprocess.gps_extractor import GPSExtractor +from preprocess.logger import setup_logger + +class GPSTimeVisualizer: + """按时间组可视化GPS点""" + + def __init__(self, image_dir: str, output_dir: str): + self.image_dir = image_dir + self.output_dir = output_dir + self.logger = logging.getLogger('UAV_Preprocess.GPSVisualizer') + + def _group_by_time(self, points_df, time_threshold=timedelta(minutes=5)): + """按时间间隔对点进行分组""" + if 'date' not in points_df.columns: + self.logger.error("数据中缺少date列") + return [points_df] + + # 将date为空的行单独作为一组 + null_date_group = points_df[points_df['date'].isna()] + valid_date_points = points_df[points_df['date'].notna()] + + if not null_date_group.empty: + self.logger.info(f"发现 {len(null_date_group)} 个无时间戳的点,将作为单独分组") + + if valid_date_points.empty: + self.logger.warning("没有有效的时间戳数据") + return [null_date_group] if not null_date_group.empty else [] + + # 按时间排序 + valid_date_points = valid_date_points.sort_values('date') + + # 计算时间差 + time_diffs = valid_date_points['date'].diff() + + # 找到时间差超过阈值的位置 + time_groups = [] + current_group_start = 0 + + for idx, time_diff in enumerate(time_diffs): + if time_diff and time_diff > time_threshold: + # 添加当前组 + current_group = valid_date_points.iloc[current_group_start:idx] + time_groups.append(current_group) + current_group_start = idx + + # 添加最后一组 + last_group = valid_date_points.iloc[current_group_start:] + if not last_group.empty: + time_groups.append(last_group) + + # 如果有空时间戳的点,将其作为最后一组 + if not null_date_group.empty: + time_groups.append(null_date_group) + + return time_groups + + def visualize_time_groups(self, time_threshold=timedelta(minutes=5)): + """在同一张图上显示所有时间组,用不同颜色区分""" + # 提取GPS数据 + extractor = GPSExtractor(self.image_dir) + gps_points = extractor.extract_all_gps() + + # 按时间分组 + time_groups = self._group_by_time(gps_points, time_threshold) + + # 创建图形 + plt.figure(figsize=(15, 10)) + + # 生成不同的颜色 + colors = plt.cm.rainbow(np.linspace(0, 1, len(time_groups))) + + # 为每个时间组绘制点和轨迹 + for idx, (group, color) in enumerate(zip(time_groups, colors)): + if not group['date'].isna().any(): + # 有时间戳的组 + sorted_group = group.sort_values('date') + + # 绘制轨迹线 + plt.plot(sorted_group['lon'], sorted_group['lat'], + color=color, linestyle='-', linewidth=1.5, alpha=0.6, + label=f'Flight Path {idx + 1}') + + # 绘制GPS点 + plt.scatter(sorted_group['lon'], sorted_group['lat'], + color=color, marker='o', s=30, alpha=0.6) + + # 标记起点和终点 + plt.scatter(sorted_group['lon'].iloc[0], sorted_group['lat'].iloc[0], + color=color, marker='^', s=100, + label=f'Start {idx + 1} ({sorted_group["date"].min().strftime("%H:%M:%S")})') + plt.scatter(sorted_group['lon'].iloc[-1], sorted_group['lat'].iloc[-1], + color=color, marker='s', s=100, + label=f'End {idx + 1} ({sorted_group["date"].max().strftime("%H:%M:%S")})') + else: + # 无时间戳的组 + plt.scatter(group['lon'], group['lat'], + color=color, marker='x', s=50, alpha=0.6, + label='No Timestamp Points') + + plt.title("GPS Points by Time Groups", fontsize=14) + plt.xlabel("Longitude", fontsize=12) + plt.ylabel("Latitude", fontsize=12) + plt.grid(True) + + # 调整图例位置和大小 + plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=10) + + # 调整布局以适应图例 + plt.tight_layout() + + # 保存图片 + plt.savefig(os.path.join(self.output_dir, 'gps_time_groups_combined.png'), + dpi=300, bbox_inches='tight') + plt.close() + + self.logger.info(f"已生成包含 {len(time_groups)} 个时间组的组合可视化图形") + + +if __name__ == '__main__': + # 设置数据集路径 + DATASET = r'F:\error_data\20241108134711\3D' + output_dir = r'E:\studio2\ODM_pro\test' + os.makedirs(output_dir, exist_ok=True) + + # 设置日志 + setup_logger(os.path.dirname(output_dir)) + + # 创建可视化器并生成图形 + visualizer = GPSTimeVisualizer(DATASET, output_dir) + visualizer.visualize_time_groups(time_threshold=timedelta(minutes=5)) \ No newline at end of file