diff --git a/odm_preprocess.py b/odm_preprocess.py index c20f76b..f79e108 100644 --- a/odm_preprocess.py +++ b/odm_preprocess.py @@ -11,12 +11,13 @@ from tqdm import tqdm from filter.cluster_filter import GPSCluster from filter.time_group_overlap_filter import TimeGroupOverlapFilter from filter.gps_filter import GPSFilter -from utils.command_runner import CommandRunner +from utils.odm_monitor import ODMProcessMonitor from utils.gps_extractor import GPSExtractor from utils.grid_divider import GridDivider from utils.logger import setup_logger from utils.visualizer import FilterVisualizer from post_pro.merge_tif import MergeTif +from tools.test_docker_run import run_docker_command @dataclass @@ -57,7 +58,7 @@ class ImagePreprocessor: # 初始化其他组件 self.logger = setup_logger(config.output_dir) self.gps_points = None - self.command_runner = CommandRunner( + self.odm_monitor = ODMProcessMonitor( config.output_dir, mode=config.mode) self.visualizer = FilterVisualizer(config.output_dir) @@ -295,9 +296,19 @@ class ImagePreprocessor: grid_points = self.divide_grids() self.copy_images(grid_points) self.logger.info("预处理任务完成") - self.command_runner.run_grid_commands( - grid_points, - ) + + # for grid_idx in grid_points.keys(): + # grid_dir = os.path.abspath(os.path.join( + # self.config.output_dir, f'grid_{grid_idx + 1}' + # )) + # grid_dir = grid_dir[0].lower() + grid_dir[1:].replace("\\", "/") + # command = f"docker run -ti --rm -v {grid_dir}:/datasets opendronemap/odm --project-path /datasets project --max-concurrency 10 --force-gps --feature-quality lowest --orthophoto-resolution 10 --fast-orthophoto --skip-3dmodel --rerun-all" + # print(command) + # stdout, stderr = run_docker_command(command) + # print(stdout) + # print(stderr) + + self.odm_monitor.process_all_grids(grid_points) self.merge_tif(grid_points) except Exception as e: self.logger.error(f"处理过程中发生错误: {str(e)}", exc_info=True) diff --git a/tools/show_GPS_by_time.py b/tools/show_GPS_by_time.py index f771275..635b0a3 100644 --- a/tools/show_GPS_by_time.py +++ b/tools/show_GPS_by_time.py @@ -6,8 +6,8 @@ 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 +from utils.gps_extractor import GPSExtractor +from utils.logger import setup_logger class GPSTimeVisualizer: """按时间组可视化GPS点""" diff --git a/tools/test_docker_run.py b/tools/test_docker_run.py index 10718ac..9f3a2f8 100644 --- a/tools/test_docker_run.py +++ b/tools/test_docker_run.py @@ -6,7 +6,7 @@ def run_docker_command(command): stdout=subprocess.PIPE, stderr=subprocess.PIPE) return result.stdout.decode('utf-8'), result.stderr.decode('utf-8') - -command = "docker run -ti --rm -v g:/ODM_output/20241024100834/grid_1:/datasets opendronemap/odm --project-path /datasets project --max-concurrency 10 --force-gps --feature-quality lowest --orthophoto-resolution 10 --fast-orthophoto --skip-3dmodel --rerun-all" -stdout, stderr = run_docker_command(command) -print(stdout) +if __name__ == "__main__": + command = "docker run -ti --rm -v g:/ODM_output/20241024100834/grid_1:/datasets opendronemap/odm --project-path /datasets project --max-concurrency 10 --force-gps --feature-quality lowest --orthophoto-resolution 10 --fast-orthophoto --skip-3dmodel --rerun-all" + stdout, stderr = run_docker_command(command) + print(stdout) diff --git a/utils/command_runner.py b/utils/command_runner.py deleted file mode 100644 index 66411fa..0000000 --- a/utils/command_runner.py +++ /dev/null @@ -1,32 +0,0 @@ -import os -import logging -from typing import Dict -import pandas as pd -from utils.odm_monitor import ODMProcessMonitor - - -class CommandRunner: - """执行网格处理命令的类""" - - def __init__(self, output_dir: str, mode: str = "快拼模式"): - self.output_dir = output_dir - self.logger = logging.getLogger('UAV_Preprocess.CommandRunner') - self.monitor = ODMProcessMonitor(mode=mode) - self.mode = mode - - def run_grid_commands(self, grid_points: Dict[int, pd.DataFrame]): - """处理所有网格""" - self.logger.info("开始执行网格处理") - for grid_idx in grid_points.keys(): - grid_dir = os.path.abspath(os.path.join( - self.output_dir, f'grid_{grid_idx + 1}' - )) - - success, error_msg = self.monitor.run_odm_with_monitor( - grid_dir=grid_dir, - grid_idx=grid_idx, - fast_mode=(self.mode == "快拼模式") - ) - - if not success: - raise Exception(f"网格 {grid_idx + 1} 处理失败: {error_msg}") diff --git a/utils/odm_monitor.py b/utils/odm_monitor.py index 1f73f86..4eb43a9 100644 --- a/utils/odm_monitor.py +++ b/utils/odm_monitor.py @@ -1,13 +1,15 @@ import os import logging import subprocess -from typing import Tuple +from typing import Dict, Tuple +import pandas as pd class ODMProcessMonitor: - """ODM进程监控器""" + """ODM处理监控器""" - def __init__(self, mode: str = "快拼模式"): + def __init__(self, output_dir: str, mode: str = "快拼模式"): + self.output_dir = output_dir self.logger = logging.getLogger('UAV_Preprocess.ODMMonitor') self.mode = mode @@ -22,47 +24,53 @@ class ODMProcessMonitor: """运行ODM命令""" self.logger.info(f"开始处理网格 {grid_idx + 1}") - # 规范化路径 - grid_dir = os.path.abspath(grid_dir).replace('\\', '/') - - # 设置环境变量 - # env = os.environ.copy() - # env["PYTHONUNBUFFERED"] = "1" - - # 构建命令字符串 - command = ( - f"docker run --rm " # 移除 -ti 参数 + # 构建Docker命令 + grid_dir = grid_dir[0].lower()+grid_dir[1:].replace('\\', '/') + docker_command = ( + f"docker run -ti --rm " f"-v {grid_dir}:/datasets " f"opendronemap/odm " f"--project-path /datasets project " f"--max-concurrency 10 " f"--force-gps " + f"--feature-quality lowest " + f"--orthophoto-resolution 10 " ) if fast_mode: - command += ( - f"--feature-quality lowest " - f"--orthophoto-resolution 8 " + docker_command += ( f"--fast-orthophoto " f"--skip-3dmodel " ) - command += "--rerun-all" - - # 执行命令 + docker_command += "--rerun-all" + self.logger.info(docker_command) result = subprocess.run( - command, - shell=True, - # env=env, - cwd=grid_dir, # 设置工作目录 - stdout=subprocess.DEVNULL, # 完全禁用输出捕获 - stderr=subprocess.DEVNULL, - creationflags=subprocess.CREATE_NO_WINDOW if os.name == 'nt' else 0 # Windows下不创建新窗口 - ) + docker_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = result.stdout.decode( + 'utf-8'), result.stderr.decode('utf-8') - # 检查是否成功完成 - if result.returncode == 0 and self._check_success(grid_dir): + # 检查执行结果 + if self._check_success(grid_dir): self.logger.info(f"网格 {grid_idx + 1} 处理成功") + self.logger.info(stdout, stderr) return True, "" - - return False, f"网格 {grid_idx + 1} 处理失败" \ No newline at end of file + + return False, f"网格 {grid_idx + 1} 处理失败" + + def process_all_grids(self, grid_points: Dict[int, pd.DataFrame]): + """处理所有网格""" + self.logger.info("开始执行网格处理") + for grid_idx in grid_points.keys(): + grid_dir = os.path.join( + self.output_dir, f'grid_{grid_idx + 1}' + ) + + success, error_msg = self.run_odm_with_monitor( + grid_dir=grid_dir, + grid_idx=grid_idx, + fast_mode=(self.mode == "快拼模式") + ) + + if not success: + raise Exception(f"网格 {grid_idx + 1} 处理失败: {error_msg}")