diff --git a/main.py b/main.py
index a51cd62..526a90f 100644
--- a/main.py
+++ b/main.py
@@ -1,6 +1,6 @@
import argparse
from datetime import timedelta
-from odm_preprocess import PreprocessConfig, ImagePreprocessor
+from odm_preprocess_fast import PreprocessConfig, ImagePreprocessor
def parse_args():
parser = argparse.ArgumentParser(description='ODM预处理工具')
diff --git a/odm_preprocess.py b/odm_preprocess.py
index 7aebb6c..69339bf 100644
--- a/odm_preprocess.py
+++ b/odm_preprocess.py
@@ -259,12 +259,12 @@ class ImagePreprocessor:
"""合并所有网格的OBJ模型并转换为OSGB格式"""
self.logger.info("开始合并OBJ模型")
merger = MergeObj(self.config.output_dir)
- center_coords = merger.merge_grid_obj(grid_points)
+ center_lon, center_lat, bounding_box = merger.merge_grid_obj(grid_points)
# 转换为OSGB格式
self.logger.info("开始转换为OSGB格式")
processor = ObjPostProcessor(self.config.output_dir)
- if not processor.convert_to_osgb(center_coords):
+ if not processor.convert_to_osgb(center_lon, center_lat, bounding_box):
self.logger.error("OSGB转换失败")
def post_process(self, successful_grid_points: Dict[tuple, pd.DataFrame], grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]):
diff --git a/odm_preprocess_fast.py b/odm_preprocess_fast.py
index 0d09d76..32237db 100644
--- a/odm_preprocess_fast.py
+++ b/odm_preprocess_fast.py
@@ -259,12 +259,12 @@ class ImagePreprocessor:
"""合并所有网格的OBJ模型并转换为OSGB格式"""
self.logger.info("开始合并OBJ模型")
merger = MergeObj(self.config.output_dir)
- center_coords = merger.merge_grid_obj(grid_points)
+ center_lon, center_lat, bounding_box = merger.merge_grid_obj(grid_points)
# 转换为OSGB格式
self.logger.info("开始转换为OSGB格式")
processor = ObjPostProcessor(self.config.output_dir)
- if not processor.convert_to_osgb(center_coords):
+ if not processor.convert_to_osgb(center_lon, center_lat, bounding_box):
self.logger.error("OSGB转换失败")
def post_process(self, successful_grid_points: Dict[tuple, pd.DataFrame], grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]):
diff --git a/post_pro/merge_obj.py b/post_pro/merge_obj.py
index df87ca5..f5408ef 100644
--- a/post_pro/merge_obj.py
+++ b/post_pro/merge_obj.py
@@ -124,6 +124,12 @@ class MergeObj:
output_model_dir = os.path.join(self.output_dir, "texturing")
os.makedirs(output_model_dir, exist_ok=True)
+ # 初始化全局边界框坐标
+ global_min_lon = float('inf')
+ global_min_lat = float('inf')
+ global_max_lon = float('-inf')
+ global_max_lat = float('-inf')
+
# 第一次遍历:获取所有grid的UTM范围
for grid_id, points in grid_points.items():
base_dir = os.path.join(
@@ -170,16 +176,28 @@ class MergeObj:
log_file = os.path.join(
base_dir, "..", "odm_orthophoto", "odm_orthophoto_log.txt")
utm_offset = self.read_utm_offset(log_file)
- modified_obj = self.modify_obj_coordinates(obj_path, utm_offset)
+ modified_obj = self.modify_obj_coordinates(
+ obj_path, utm_offset)
# 读取obj文件内容
- vertices, tex_coords, normals, faces, face_materials, _ = self.read_obj(modified_obj)
+ vertices, tex_coords, normals, faces, face_materials, _ = self.read_obj(
+ modified_obj)
# 计算当前grid的中心点
- grid_center_lon, grid_center_lat = self.get_center_coordinates(vertices)
+ grid_center_lon, grid_center_lat, grid_bounding_box = self.get_center_coordinates(
+ vertices)
grid_centers.append((grid_center_lon, grid_center_lat))
self.logger.info(
f"网格 ({grid_id[0]},{grid_id[1]}) 中心点经纬度: ({grid_center_lon}, {grid_center_lat})")
+ # 更新全局边界框坐标
+ global_min_lon = min(
+ global_min_lon, grid_bounding_box['LB_lon'])
+ global_min_lat = min(
+ global_min_lat, grid_bounding_box['LB_lat'])
+ global_max_lon = max(
+ global_max_lon, grid_bounding_box['RU_lon'])
+ global_max_lat = max(
+ global_max_lat, grid_bounding_box['RU_lat'])
# 复制并重命名纹理文件
texture_map = self.copy_and_rename_texture(
@@ -211,13 +229,16 @@ class MergeObj:
for face, material in zip(faces, face_materials):
# 调整面的索引
new_face_v = [f + v_offset for f in face[0]]
- new_face_vt = [f + vt_offset for f in face[1]] if face[1] else []
- new_face_vn = [f + vn_offset for f in face[2]] if face[2] else []
+ new_face_vt = [
+ f + vt_offset for f in face[1]] if face[1] else []
+ new_face_vn = [
+ f + vn_offset for f in face[2]] if face[2] else []
all_faces.append((new_face_v, new_face_vt, new_face_vn))
-
+
# 添加材质前缀
if material:
- all_face_materials.append(f"material_{grid_id[0]}_{grid_id[1]}_{material}")
+ all_face_materials.append(
+ f"material_{grid_id[0]}_{grid_id[1]}_{material}")
else:
all_face_materials.append(material)
@@ -240,23 +261,29 @@ class MergeObj:
all_faces, all_face_materials, "textured_model.mtl")
# 计算整体中心点
- center_lon = sum(center[0] for center in grid_centers) / len(grid_centers)
- center_lat = sum(center[1] for center in grid_centers) / len(grid_centers)
+ center_lon = sum(center[0]
+ for center in grid_centers) / len(grid_centers)
+ center_lat = sum(center[1]
+ for center in grid_centers) / len(grid_centers)
self.logger.info(f"模型整体中心点经纬度: ({center_lon}, {center_lat})")
-
- return center_lon, center_lat
+ # 计算整个区域的边界框
+ bounding_box = [global_min_lon, global_min_lat, global_max_lon, global_max_lat]
+ self.logger.info(
+ f"模型整体边界框: ({bounding_box[0]}, {bounding_box[1]}) - ({bounding_box[2]}, {bounding_box[3]})")
+
+ return center_lon, center_lat, bounding_box
except Exception as e:
self.logger.error(f"合并过程中发生错误: {str(e)}", exc_info=True)
raise
- def get_center_coordinates(self, vertices: List[List[float]]) -> Tuple[float, float]:
+ def get_center_coordinates(self, vertices: List[List[float]]) -> Tuple[float, float, Dict[str, float]]:
"""计算顶点的中心点UTM坐标,并转换为WGS84经纬度。
注意:顶点坐标是相对于整体最小UTM坐标的偏移值,需要加回最小UTM坐标。
Args:
vertices: 顶点列表,每个顶点是[x, y, z]格式,x和y是相对于最小UTM坐标的偏移
Returns:
- Tuple[float, float]: (longitude, latitude)经纬度坐标
+ Tuple[float, float, Dict[str, float]]: (longitude, latitude, bounding_box)
"""
# 计算相对坐标的边界框
x_coords = [v[0] for v in vertices]
@@ -272,8 +299,16 @@ class MergeObj:
# 转换为WGS84经纬度
lon, lat = self.transformer.transform(center_x_utm, center_y_utm)
+ # 计算边界框并转换为经纬度
+ bounding_box = {
+ 'LB_lon': self.transformer.transform(min(x_coords) + self.min_east, min(y_coords) + self.min_north)[0],
+ 'LB_lat': self.transformer.transform(min(x_coords) + self.min_east, min(y_coords) + self.min_north)[1],
+ 'RU_lon': self.transformer.transform(max(x_coords) + self.min_east, max(y_coords) + self.min_north)[0],
+ 'RU_lat': self.transformer.transform(max(x_coords) + self.min_east, max(y_coords) + self.min_north)[1]
+ }
+
self.logger.info(f"模型UTM中心点: ({center_x_utm}, {center_y_utm})")
- return lon, lat
+ return lon, lat, bounding_box
def read_mtl(self, mtl_path: str) -> dict:
"""读取MTL文件内容
diff --git a/post_pro/obj_post_pro.py b/post_pro/obj_post_pro.py
index b5a95e6..af3d49c 100644
--- a/post_pro/obj_post_pro.py
+++ b/post_pro/obj_post_pro.py
@@ -1,7 +1,7 @@
import os
import logging
import subprocess
-from typing import Tuple
+from typing import Tuple, Dict
class ObjPostProcessor:
@@ -9,7 +9,7 @@ class ObjPostProcessor:
self.output_dir = output_dir
self.logger = logging.getLogger('UAV_Preprocess.ObjPostProcessor')
- def create_metadata_xml(self, osgb_dir: str, lon: float, lat: float):
+ def create_metadata_xml(self, osgb_dir: str, lon: float, lat: float, bounding_box):
"""创建metadata.xml文件,包含地理参考信息
Args:
osgb_dir: osgb输出目录
@@ -18,15 +18,29 @@ class ObjPostProcessor:
"""
try:
metadata_content = f'''
-
-
- EPSG:4326
-
- {lon},{lat},0.000000
-
- Visible
-
-'''
+
+
+ EPSG:4326
+
+
+ {lon},{lat},0.000000
+
+
+
+
+ {bounding_box[0]}
+ {bounding_box[1]}
+
+
+ {bounding_box[2]}
+ {bounding_box[3]}
+
+
+
+ Visible
+
+
+ '''
# metadata.xml 放在根目录
metadata_path = os.path.join(osgb_dir, 'metadata.xml')
@@ -39,7 +53,7 @@ class ObjPostProcessor:
self.logger.error(f"创建metadata.xml时发生错误: {str(e)}")
raise
- def convert_to_osgb(self, center_coords: Tuple[float, float]):
+ def convert_to_osgb(self, center_lon, center_lat, bounding_box):
"""将obj转换为osgb,并创建metadata.xml
Args:
center_coords: (longitude, latitude)中心点经纬度坐标
@@ -76,12 +90,11 @@ class ObjPostProcessor:
if result.returncode != 0:
raise Exception(f"osgb格式转换失败: {result.stderr}")
+ self.logger.info(f"转换完成: {output_osgb}")
# 创建metadata.xml
- lon, lat = center_coords
- self.create_metadata_xml(osgb_dir, lon, lat)
+ self.create_metadata_xml(osgb_dir, center_lon, center_lat, bounding_box)
- self.logger.info(f"转换完成: {output_osgb}")
return True
except Exception as e: