From df74970ca9c6326fede3898325f903bb33a0be34 Mon Sep 17 00:00:00 2001 From: weixin_46229132 Date: Thu, 6 Feb 2025 16:54:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0obj=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- odm_preprocess.py | 22 ++++++++----- post_pro/conv_obj.py | 78 ++++++++++++++++++++++++++++++++++++++++++++ run_odm.bat | 6 ---- 3 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 post_pro/conv_obj.py delete mode 100644 run_odm.bat diff --git a/odm_preprocess.py b/odm_preprocess.py index cc86c04..835b428 100644 --- a/odm_preprocess.py +++ b/odm_preprocess.py @@ -4,10 +4,7 @@ from datetime import timedelta from dataclasses import dataclass from typing import Dict, Tuple import psutil - -import matplotlib.pyplot as plt import pandas as pd -from tqdm import tqdm from filter.cluster_filter import GPSCluster from filter.time_group_overlap_filter import TimeGroupOverlapFilter @@ -20,6 +17,7 @@ from utils.visualizer import FilterVisualizer from post_pro.merge_tif import MergeTif from post_pro.merge_obj import MergeObj from post_pro.merge_laz import MergePly +from post_pro.conv_obj import ConvertOBJ @dataclass @@ -235,7 +233,7 @@ class ImagePreprocessor: os.makedirs(output_dir, exist_ok=True) - for point in tqdm(points, desc=f"复制网格 ({grid_id[0]},{grid_id[1]}) 的图像"): + for point in points: src = os.path.join(self.config.image_dir, point["file"]) dst = os.path.join(output_dir, point["file"]) shutil.copy(src, dst) @@ -260,6 +258,12 @@ class ImagePreprocessor: merger = MergeObj(self.config.output_dir) merger.merge_grid_obj(grid_points, translations) + def convert_obj(self, grid_points: Dict[tuple, pd.DataFrame]): + """转换OBJ模型""" + self.logger.info("开始转换OBJ模型") + converter = ConvertOBJ(self.config.output_dir) + converter.convert_grid_obj(grid_points) + def post_process(self, successful_grid_points: Dict[tuple, pd.DataFrame], grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]): """后处理:合并或复制处理结果""" if len(successful_grid_points) < len(grid_points): @@ -271,12 +275,14 @@ class ImagePreprocessor: if self.config.mode == "快拼模式": self.merge_tif(successful_grid_points, self.config.produce_dem) elif self.config.mode == "三维模式": - self.merge_ply(successful_grid_points) - self.merge_obj(successful_grid_points, translations) + # self.merge_ply(successful_grid_points) + # self.merge_obj(successful_grid_points, translations) + self.convert_obj(successful_grid_points) else: self.merge_tif(successful_grid_points, self.config.produce_dem) - self.merge_ply(successful_grid_points) - self.merge_obj(successful_grid_points, translations) + # self.merge_ply(successful_grid_points) + # self.merge_obj(successful_grid_points, translations) + self.convert_obj(successful_grid_points) def process(self): """执行完整的预处理流程""" diff --git a/post_pro/conv_obj.py b/post_pro/conv_obj.py new file mode 100644 index 0000000..3480448 --- /dev/null +++ b/post_pro/conv_obj.py @@ -0,0 +1,78 @@ +import os +import subprocess +import json +import shutil +import logging + +class ConvertOBJ: + def __init__(self, output_dir: str): + self.output_dir = output_dir + self.logger = logging.getLogger('UAV_Preprocess.ConvertOBJ') + + def convert_grid_obj(self, grid_points): + """转换每个网格的OBJ文件为OSGB格式""" + os.makedirs(os.path.join(self.output_dir, "osgb"), exist_ok=True) + for grid_id in grid_points.keys(): + try: + self._convert_single_grid(grid_id) + except Exception as e: + self.logger.error(f"网格 {grid_id} 转换失败: {str(e)}") + + def _convert_single_grid(self, grid_id): + """转换单个网格的OBJ文件""" + # 1. 构建相关路径 + grid_name = f"grid_{grid_id[0]}_{grid_id[1]}" + project_dir = os.path.join(self.output_dir, grid_name, "project") + texturing_dir = os.path.join(project_dir, "odm_texturing") + opensfm_dir = os.path.join(project_dir, "opensfm") + + # 检查输入文件是否存在 + obj_file = os.path.join(texturing_dir, "odm_textured_model_geo.obj") + if not os.path.exists(obj_file): + raise FileNotFoundError(f"找不到OBJ文件: {obj_file}") + + # 2. 执行格式转换 + self.logger.info(f"开始转换网格 {grid_id} 的OBJ文件") + output_osgb = os.path.join(texturing_dir, "Tile.osgb") + + cmd = ( + f"osgconv --compressed --smooth --fix-transparency -o 0,1,0-0,0,-1 " + f"{obj_file} {output_osgb}" + ) + + try: + subprocess.run(cmd, shell=True, check=True, cwd=texturing_dir) + except subprocess.CalledProcessError as e: + raise RuntimeError(f"OSGB转换失败: {str(e)}") + + # 3. 读取地理信息 + ref_lla_file = os.path.join(opensfm_dir, "reference_lla.json") + with open(ref_lla_file, 'r') as f: + ref_lla = json.load(f) + + # 4. 创建OSGB目录结构 + osgb_dir = os.path.join(self.output_dir, "osgb", grid_name) + data_dir = os.path.join(osgb_dir, "Data") + tile_dir = os.path.join(data_dir, "Tile") + os.makedirs(tile_dir, exist_ok=True) + + # 5. 创建metadata.xml + metadata_content = f""" + + + EPSG:4326 + + {ref_lla['longitude']},{ref_lla['latitude']},0.000000 + + Visible + +""" + + metadata_file = os.path.join(osgb_dir, "metadata.xml") + with open(metadata_file, 'w', encoding='utf-8') as f: + f.write(metadata_content) + + # 6. 复制OSGB文件 + shutil.copy2(output_osgb, os.path.join(tile_dir, "Tile.osgb")) + + self.logger.info(f"网格 {grid_id} 转换完成") diff --git a/run_odm.bat b/run_odm.bat deleted file mode 100644 index c327f15..0000000 --- a/run_odm.bat +++ /dev/null @@ -1,6 +0,0 @@ -@echo off -set IMAGE_DIR=E:\datasets\UAV\134\project\images\ -set OUTPUT_DIR=G:\ODM_output\134 - -python main.py --image_dir %IMAGE_DIR% --output_dir %OUTPUT_DIR% --mode 三维模式 -pause \ No newline at end of file