subprocess.run,基于test_docker_run.py

This commit is contained in:
龙澳 2024-12-28 11:06:03 +08:00
parent 6ad875d59a
commit a7eb5f5216
5 changed files with 61 additions and 74 deletions

View File

@ -11,12 +11,13 @@ from tqdm import tqdm
from filter.cluster_filter import GPSCluster from filter.cluster_filter import GPSCluster
from filter.time_group_overlap_filter import TimeGroupOverlapFilter from filter.time_group_overlap_filter import TimeGroupOverlapFilter
from filter.gps_filter import GPSFilter 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.gps_extractor import GPSExtractor
from utils.grid_divider import GridDivider from utils.grid_divider import GridDivider
from utils.logger import setup_logger from utils.logger import setup_logger
from utils.visualizer import FilterVisualizer from utils.visualizer import FilterVisualizer
from post_pro.merge_tif import MergeTif from post_pro.merge_tif import MergeTif
from tools.test_docker_run import run_docker_command
@dataclass @dataclass
@ -57,7 +58,7 @@ class ImagePreprocessor:
# 初始化其他组件 # 初始化其他组件
self.logger = setup_logger(config.output_dir) self.logger = setup_logger(config.output_dir)
self.gps_points = None self.gps_points = None
self.command_runner = CommandRunner( self.odm_monitor = ODMProcessMonitor(
config.output_dir, mode=config.mode) config.output_dir, mode=config.mode)
self.visualizer = FilterVisualizer(config.output_dir) self.visualizer = FilterVisualizer(config.output_dir)
@ -295,9 +296,19 @@ class ImagePreprocessor:
grid_points = self.divide_grids() grid_points = self.divide_grids()
self.copy_images(grid_points) self.copy_images(grid_points)
self.logger.info("预处理任务完成") 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) self.merge_tif(grid_points)
except Exception as e: except Exception as e:
self.logger.error(f"处理过程中发生错误: {str(e)}", exc_info=True) self.logger.error(f"处理过程中发生错误: {str(e)}", exc_info=True)

View File

@ -6,8 +6,8 @@ import matplotlib.pyplot as plt
from datetime import timedelta from datetime import timedelta
import logging import logging
import numpy as np import numpy as np
from preprocess.gps_extractor import GPSExtractor from utils.gps_extractor import GPSExtractor
from preprocess.logger import setup_logger from utils.logger import setup_logger
class GPSTimeVisualizer: class GPSTimeVisualizer:
"""按时间组可视化GPS点""" """按时间组可视化GPS点"""

View File

@ -6,7 +6,7 @@ def run_docker_command(command):
stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return result.stdout.decode('utf-8'), result.stderr.decode('utf-8') return result.stdout.decode('utf-8'), result.stderr.decode('utf-8')
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" 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) stdout, stderr = run_docker_command(command)
print(stdout) print(stdout)

View File

@ -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}")

View File

@ -1,13 +1,15 @@
import os import os
import logging import logging
import subprocess import subprocess
from typing import Tuple from typing import Dict, Tuple
import pandas as pd
class ODMProcessMonitor: 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.logger = logging.getLogger('UAV_Preprocess.ODMMonitor')
self.mode = mode self.mode = mode
@ -22,47 +24,53 @@ class ODMProcessMonitor:
"""运行ODM命令""" """运行ODM命令"""
self.logger.info(f"开始处理网格 {grid_idx + 1}") self.logger.info(f"开始处理网格 {grid_idx + 1}")
# 规范化路径 # 构建Docker命令
grid_dir = os.path.abspath(grid_dir).replace('\\', '/') grid_dir = grid_dir[0].lower()+grid_dir[1:].replace('\\', '/')
docker_command = (
# 设置环境变量 f"docker run -ti --rm "
# env = os.environ.copy()
# env["PYTHONUNBUFFERED"] = "1"
# 构建命令字符串
command = (
f"docker run --rm " # 移除 -ti 参数
f"-v {grid_dir}:/datasets " f"-v {grid_dir}:/datasets "
f"opendronemap/odm " f"opendronemap/odm "
f"--project-path /datasets project " f"--project-path /datasets project "
f"--max-concurrency 10 " f"--max-concurrency 10 "
f"--force-gps " f"--force-gps "
f"--feature-quality lowest "
f"--orthophoto-resolution 10 "
) )
if fast_mode: if fast_mode:
command += ( docker_command += (
f"--feature-quality lowest "
f"--orthophoto-resolution 8 "
f"--fast-orthophoto " f"--fast-orthophoto "
f"--skip-3dmodel " f"--skip-3dmodel "
) )
command += "--rerun-all" docker_command += "--rerun-all"
self.logger.info(docker_command)
# 执行命令
result = subprocess.run( result = subprocess.run(
command, docker_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
shell=True, stdout, stderr = result.stdout.decode(
# env=env, 'utf-8'), result.stderr.decode('utf-8')
cwd=grid_dir, # 设置工作目录
stdout=subprocess.DEVNULL, # 完全禁用输出捕获
stderr=subprocess.DEVNULL,
creationflags=subprocess.CREATE_NO_WINDOW if os.name == 'nt' else 0 # Windows下不创建新窗口
)
# 检查是否成功完成 # 检查执行结果
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(f"网格 {grid_idx + 1} 处理成功")
self.logger.info(stdout, stderr)
return True, "" return True, ""
return False, f"网格 {grid_idx + 1} 处理失败" 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}")