可视化模块修改
This commit is contained in:
parent
5c382e1810
commit
a3a5e5738a
@ -15,8 +15,11 @@ class DirectoryManager:
|
|||||||
def clean_output_dir(self):
|
def clean_output_dir(self):
|
||||||
"""清理输出目录"""
|
"""清理输出目录"""
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(self.config.output_dir)
|
if os.path.exists(self.config.output_dir):
|
||||||
print(f"已清理输出目录: {self.config.output_dir}")
|
shutil.rmtree(self.config.output_dir)
|
||||||
|
print(f"已清理输出目录: {self.config.output_dir}")
|
||||||
|
else:
|
||||||
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"清理输出目录时发生错误: {str(e)}")
|
print(f"清理输出目录时发生错误: {str(e)}")
|
||||||
raise
|
raise
|
||||||
@ -65,7 +68,7 @@ class DirectoryManager:
|
|||||||
free_space = disk_usage.free
|
free_space = disk_usage.free
|
||||||
|
|
||||||
# 计算所需空间(输入大小的10倍)
|
# 计算所需空间(输入大小的10倍)
|
||||||
required_space = input_size * 10
|
required_space = input_size * 8
|
||||||
|
|
||||||
if free_space < required_space:
|
if free_space < required_space:
|
||||||
error_msg = (
|
error_msg = (
|
||||||
|
@ -2,34 +2,35 @@ import logging
|
|||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
def setup_logger(output_dir):
|
def setup_logger(output_dir):
|
||||||
# 创建logs目录
|
# 创建logs目录
|
||||||
log_dir = os.path.join(output_dir, 'logs')
|
log_dir = os.path.join(output_dir, 'logs')
|
||||||
|
|
||||||
# 创建日志文件名(包含时间戳)
|
# 创建日志文件名(包含时间戳)
|
||||||
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||||
log_file = os.path.join(log_dir, f'preprocess_{timestamp}.log')
|
log_file = os.path.join(log_dir, f'preprocess_{timestamp}.log')
|
||||||
|
|
||||||
# 配置日志格式
|
# 配置日志格式
|
||||||
formatter = logging.Formatter(
|
formatter = logging.Formatter(
|
||||||
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||||
datefmt='%Y-%m-%d %H:%M:%S'
|
datefmt='%Y-%m-%d %H:%M:%S'
|
||||||
)
|
)
|
||||||
|
|
||||||
# 配置文件处理器
|
# 配置文件处理器
|
||||||
file_handler = logging.FileHandler(log_file, encoding='utf-8')
|
file_handler = logging.FileHandler(log_file, encoding='utf-8')
|
||||||
file_handler.setFormatter(formatter)
|
file_handler.setFormatter(formatter)
|
||||||
|
|
||||||
# 配置控制台处理器
|
# 配置控制台处理器
|
||||||
console_handler = logging.StreamHandler()
|
console_handler = logging.StreamHandler()
|
||||||
console_handler.setFormatter(formatter)
|
console_handler.setFormatter(formatter)
|
||||||
|
|
||||||
# 获取根日志记录器
|
# 获取根日志记录器
|
||||||
logger = logging.getLogger('UAV_Preprocess')
|
logger = logging.getLogger('UAV_Preprocess')
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
# 添加处理器
|
# 添加处理器
|
||||||
logger.addHandler(file_handler)
|
logger.addHandler(file_handler)
|
||||||
logger.addHandler(console_handler)
|
logger.addHandler(console_handler)
|
||||||
|
|
||||||
return logger
|
return logger
|
||||||
|
@ -85,21 +85,20 @@ class ODMProcessMonitor:
|
|||||||
self.logger.error("容器运行失败的详细错误日志:")
|
self.logger.error("容器运行失败的详细错误日志:")
|
||||||
for line in error_msg:
|
for line in error_msg:
|
||||||
self.logger.error(line)
|
self.logger.error(line)
|
||||||
|
container.remove()
|
||||||
|
time.sleep(5)
|
||||||
else:
|
else:
|
||||||
# 获取所有日志
|
# 获取所有日志
|
||||||
logs = container.logs().decode("utf-8").splitlines()
|
logs = container.logs().decode("utf-8").splitlines()
|
||||||
|
|
||||||
# 输出最后 50 行日志
|
# 输出最后 50 行日志
|
||||||
self.logger.info("容器运行完成,以下是最后 50 行日志:")
|
self.logger.info("容器运行完成,以下是最后 50 行日志:")
|
||||||
for line in logs[-50:]:
|
for line in logs[-50:]:
|
||||||
self.logger.info(line)
|
self.logger.info(line)
|
||||||
success = True
|
success = True
|
||||||
error_msg = ""
|
error_msg = ""
|
||||||
|
container.remove()
|
||||||
break
|
break
|
||||||
|
|
||||||
# 删除容器
|
|
||||||
container.remove()
|
|
||||||
time.sleep(5)
|
|
||||||
|
|
||||||
return success, error_msg
|
return success, error_msg
|
||||||
|
|
||||||
|
@ -8,11 +8,11 @@ from pyproj import Transformer
|
|||||||
|
|
||||||
class FilterVisualizer:
|
class FilterVisualizer:
|
||||||
"""过滤结果可视化器"""
|
"""过滤结果可视化器"""
|
||||||
|
|
||||||
def __init__(self, output_dir: str):
|
def __init__(self, output_dir: str):
|
||||||
"""
|
"""
|
||||||
初始化可视化器
|
初始化可视化器
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
output_dir: 输出目录路径
|
output_dir: 输出目录路径
|
||||||
"""
|
"""
|
||||||
@ -24,28 +24,28 @@ class FilterVisualizer:
|
|||||||
"EPSG:32649", # UTM49N
|
"EPSG:32649", # UTM49N
|
||||||
always_xy=True
|
always_xy=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def _convert_to_utm(self, lon: pd.Series, lat: pd.Series) -> tuple:
|
def _convert_to_utm(self, lon: pd.Series, lat: pd.Series) -> tuple:
|
||||||
"""
|
"""
|
||||||
将经纬度坐标转换为UTM坐标
|
将经纬度坐标转换为UTM坐标
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
lon: 经度序列
|
lon: 经度序列
|
||||||
lat: 纬度序列
|
lat: 纬度序列
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
tuple: (x坐标, y坐标)
|
tuple: (x坐标, y坐标)
|
||||||
"""
|
"""
|
||||||
return self.transformer.transform(lon, lat)
|
return self.transformer.transform(lon, lat)
|
||||||
|
|
||||||
def visualize_filter_step(self,
|
def visualize_filter_step(self,
|
||||||
current_points: pd.DataFrame,
|
current_points: pd.DataFrame,
|
||||||
previous_points: pd.DataFrame,
|
previous_points: pd.DataFrame,
|
||||||
step_name: str,
|
step_name: str,
|
||||||
save_name: Optional[str] = None):
|
save_name: Optional[str] = None):
|
||||||
"""
|
"""
|
||||||
可视化单个过滤步骤的结果
|
可视化单个过滤步骤的结果
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
current_points: 当前步骤后的点
|
current_points: 当前步骤后的点
|
||||||
previous_points: 上一步骤的点
|
previous_points: 上一步骤的点
|
||||||
@ -53,39 +53,43 @@ class FilterVisualizer:
|
|||||||
save_name: 保存文件名,默认为step_name
|
save_name: 保存文件名,默认为step_name
|
||||||
"""
|
"""
|
||||||
self.logger.info(f"开始生成{step_name}的可视化结果")
|
self.logger.info(f"开始生成{step_name}的可视化结果")
|
||||||
|
|
||||||
# 找出被过滤掉的点
|
# 找出被过滤掉的点
|
||||||
filtered_files = set(previous_points['file']) - set(current_points['file'])
|
filtered_files = set(
|
||||||
filtered_points = previous_points[previous_points['file'].isin(filtered_files)]
|
previous_points['file']) - set(current_points['file'])
|
||||||
|
filtered_points = previous_points[previous_points['file'].isin(
|
||||||
|
filtered_files)]
|
||||||
|
|
||||||
# 转换坐标到UTM
|
# 转换坐标到UTM
|
||||||
current_x, current_y = self._convert_to_utm(current_points['lon'], current_points['lat'])
|
current_x, current_y = self._convert_to_utm(
|
||||||
filtered_x, filtered_y = self._convert_to_utm(filtered_points['lon'], filtered_points['lat'])
|
current_points['lon'], current_points['lat'])
|
||||||
|
filtered_x, filtered_y = self._convert_to_utm(
|
||||||
|
filtered_points['lon'], filtered_points['lat'])
|
||||||
|
|
||||||
# 创建图形
|
# 创建图形
|
||||||
plt.rcParams['font.sans-serif']=['SimHei']#黑体
|
plt.rcParams['font.sans-serif'] = ['SimHei'] # 黑体
|
||||||
plt.rcParams['axes.unicode_minus'] = False
|
plt.rcParams['axes.unicode_minus'] = False
|
||||||
plt.figure()
|
plt.figure(figsize=(20, 20))
|
||||||
|
|
||||||
# 绘制保留的点
|
# 绘制保留的点
|
||||||
plt.scatter(current_x, current_y,
|
plt.scatter(current_x, current_y,
|
||||||
color='blue', label='保留的点',
|
color='blue', label='保留的点',
|
||||||
alpha=0.6, s=50)
|
alpha=0.6, s=5)
|
||||||
|
|
||||||
# 绘制被过滤的点
|
# 绘制被过滤的点
|
||||||
if not filtered_points.empty:
|
if not filtered_points.empty:
|
||||||
plt.scatter(filtered_x, filtered_y,
|
plt.scatter(filtered_x, filtered_y,
|
||||||
color='red', marker='x', label='过滤的点',
|
color='red', marker='x', label='过滤的点')
|
||||||
alpha=0.6, s=100)
|
|
||||||
|
|
||||||
# 设置图形属性
|
# 设置图形属性
|
||||||
plt.title(f"{step_name}后的GPS点\n"
|
plt.title(f"{step_name}后的GPS点\n"
|
||||||
f"(过滤: {len(filtered_points)}, 保留: {len(current_points)})",
|
f"(过滤: {len(filtered_points)}, 保留: {len(current_points)})",
|
||||||
fontsize=14)
|
fontsize=14)
|
||||||
plt.xlabel("东向坐标 (米)", fontsize=12)
|
plt.xlabel("东向坐标 (米)", fontsize=12)
|
||||||
plt.ylabel("北向坐标 (米)", fontsize=12)
|
plt.ylabel("北向坐标 (米)", fontsize=12)
|
||||||
plt.grid(True)
|
plt.grid(True)
|
||||||
|
plt.axis('equal')
|
||||||
|
|
||||||
# 添加统计信息
|
# 添加统计信息
|
||||||
stats_text = (
|
stats_text = (
|
||||||
f"原始点数: {len(previous_points)}\n"
|
f"原始点数: {len(previous_points)}\n"
|
||||||
@ -94,20 +98,21 @@ class FilterVisualizer:
|
|||||||
f"过滤率: {len(filtered_points)/len(previous_points)*100:.1f}%"
|
f"过滤率: {len(filtered_points)/len(previous_points)*100:.1f}%"
|
||||||
)
|
)
|
||||||
plt.figtext(0.02, 0.02, stats_text, fontsize=10,
|
plt.figtext(0.02, 0.02, stats_text, fontsize=10,
|
||||||
bbox=dict(facecolor='white', alpha=0.8))
|
bbox=dict(facecolor='white', alpha=0.8))
|
||||||
|
|
||||||
# 添加图例
|
# 添加图例
|
||||||
plt.legend(loc='upper right', fontsize=10)
|
plt.legend(loc='upper right', fontsize=10)
|
||||||
|
|
||||||
# 调整布局
|
# 调整布局
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
|
|
||||||
# 保存图形
|
# 保存图形
|
||||||
save_name = save_name or step_name.lower().replace(' ', '_')
|
save_name = save_name or step_name.lower().replace(' ', '_')
|
||||||
save_path = os.path.join(self.output_dir, 'filter_imgs', f'filter_{save_name}.png')
|
save_path = os.path.join(
|
||||||
|
self.output_dir, 'filter_imgs', f'filter_{save_name}.png')
|
||||||
plt.savefig(save_path, dpi=300, bbox_inches='tight')
|
plt.savefig(save_path, dpi=300, bbox_inches='tight')
|
||||||
plt.close()
|
plt.close()
|
||||||
|
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
f"{step_name}过滤可视化结果已保存至 {save_path}\n"
|
f"{step_name}过滤可视化结果已保存至 {save_path}\n"
|
||||||
f"过滤掉 {len(filtered_points)} 个点,"
|
f"过滤掉 {len(filtered_points)} 个点,"
|
||||||
@ -120,11 +125,11 @@ if __name__ == '__main__':
|
|||||||
# 测试代码
|
# 测试代码
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
# 创建测试数据
|
# 创建测试数据
|
||||||
np.random.seed(42)
|
np.random.seed(42)
|
||||||
n_points = 1000
|
n_points = 1000
|
||||||
|
|
||||||
# 生成随机点
|
# 生成随机点
|
||||||
test_data = pd.DataFrame({
|
test_data = pd.DataFrame({
|
||||||
'lon': np.random.uniform(120, 121, n_points),
|
'lon': np.random.uniform(120, 121, n_points),
|
||||||
@ -132,16 +137,16 @@ if __name__ == '__main__':
|
|||||||
'file': [f'img_{i}.jpg' for i in range(n_points)],
|
'file': [f'img_{i}.jpg' for i in range(n_points)],
|
||||||
'date': [datetime.now() for _ in range(n_points)]
|
'date': [datetime.now() for _ in range(n_points)]
|
||||||
})
|
})
|
||||||
|
|
||||||
# 随机选择点作为过滤后的结果
|
# 随机选择点作为过滤后的结果
|
||||||
filtered_data = test_data.sample(n=800)
|
filtered_data = test_data.sample(n=800)
|
||||||
|
|
||||||
# 测试可视化
|
# 测试可视化
|
||||||
visualizer = FilterVisualizer('test_output')
|
visualizer = FilterVisualizer('test_output')
|
||||||
os.makedirs('test_output', exist_ok=True)
|
os.makedirs('test_output', exist_ok=True)
|
||||||
|
|
||||||
visualizer.visualize_filter_step(
|
visualizer.visualize_filter_step(
|
||||||
filtered_data,
|
filtered_data,
|
||||||
test_data,
|
test_data,
|
||||||
"Test Filter"
|
"Test Filter"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user