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.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)

View File

@ -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点"""

View File

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

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 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} 处理失败"
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}")