diff --git a/odm_preprocess.py b/odm_preprocess.py
index cc07a99..3c4a5ce 100644
--- a/odm_preprocess.py
+++ b/odm_preprocess.py
@@ -298,8 +298,8 @@ class ImagePreprocessor:
self.cluster()
self.filter_isolated_points()
self.filter_time_group_overlap()
- center_lat, center_lon = self.calculate_center_coordinates()
# self.filter_alternate_images()
+ center_lat, center_lon = self.calculate_center_coordinates()
grid_points, translations = self.divide_grids()
self.copy_images(grid_points)
self.logger.info("预处理任务完成")
diff --git a/odm_preprocess_fast.py b/odm_preprocess_fast.py
index d97a795..805dc88 100644
--- a/odm_preprocess_fast.py
+++ b/odm_preprocess_fast.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
@@ -187,6 +185,28 @@ class ImagePreprocessor:
self.visualizer.visualize_filter_step(
self.gps_points, previous_points, "3-Time Group Overlap")
+ def calculate_center_coordinates(self):
+ """计算剩余点的中心经纬度坐标"""
+ mean_lat = self.gps_points['lat'].mean()
+ mean_lon = self.gps_points['lon'].mean()
+ self.logger.info(f"区域中心坐标:纬度 {mean_lat:.6f}, 经度 {mean_lon:.6f}")
+ return mean_lat, mean_lon
+
+ def filter_alternate_images(self):
+ """按时间顺序隔一个删一个图像来降低密度"""
+ previous_points = self.gps_points.copy()
+
+ # 按时间戳排序
+ self.gps_points = self.gps_points.sort_values('date')
+
+ # 保留索引为偶数的行(即隔一个保留一个)
+ self.gps_points = self.gps_points.iloc[::2].reset_index(drop=True)
+
+ self.visualizer.visualize_filter_step(
+ self.gps_points, previous_points, "4-Alternate Images")
+
+ self.logger.info(f"交替过滤后剩余 {len(self.gps_points)} 个点")
+
def divide_grids(self) -> Tuple[Dict[tuple, pd.DataFrame], Dict[tuple, tuple]]:
"""划分网格
Returns:
@@ -220,7 +240,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)
@@ -245,7 +265,13 @@ class ImagePreprocessor:
merger = MergeObj(self.config.output_dir)
merger.merge_grid_obj(grid_points, translations)
- def post_process(self, successful_grid_points: Dict[tuple, pd.DataFrame], grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]):
+ def convert_obj(self, grid_points: Dict[tuple, pd.DataFrame], center_lat: float, center_lon: float):
+ """转换OBJ模型"""
+ self.logger.info("开始转换OBJ模型")
+ converter = ConvertOBJ(self.config.output_dir, center_lat, center_lon)
+ 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], center_lat: float, center_lon: float):
"""后处理:合并或复制处理结果"""
if len(successful_grid_points) < len(grid_points):
self.logger.warning(
@@ -256,12 +282,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, center_lat, center_lon)
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, center_lat, center_lon)
def process(self):
"""执行完整的预处理流程"""
@@ -270,15 +298,17 @@ class ImagePreprocessor:
self.cluster()
self.filter_isolated_points()
self.filter_time_group_overlap()
+ center_lat, center_lon = self.calculate_center_coordinates()
+ # self.filter_alternate_images()
grid_points, translations = self.divide_grids()
# self.copy_images(grid_points)
- self.logger.info("预处理任务完成")
+ # self.logger.info("预处理任务完成")
# successful_grid_points = self.odm_monitor.process_all_grids(
# grid_points, self.config.produce_dem)
successful_grid_points = grid_points
self.post_process(successful_grid_points,
- grid_points, translations)
+ grid_points, translations, center_lat, center_lon)
except Exception as e:
self.logger.error(f"处理过程中发生错误: {str(e)}", exc_info=True)
diff --git a/post_pro/conv_obj.py b/post_pro/conv_obj.py
index 5f495fa..589597c 100644
--- a/post_pro/conv_obj.py
+++ b/post_pro/conv_obj.py
@@ -13,17 +13,19 @@ class ConvertOBJ:
def convert_grid_obj(self, grid_points):
"""转换每个网格的OBJ文件为OSGB格式"""
- os.makedirs(os.path.join(self.output_dir, "osgb"), exist_ok=True)
+ os.makedirs(os.path.join(self.output_dir, "osgb", "Data"), exist_ok=True)
+ tile_infos = []
+
for grid_id in grid_points.keys():
try:
- self._convert_single_grid(grid_id)
+ tile_info = self._convert_single_grid(grid_id, grid_points)
+ tile_infos.append(tile_info)
except Exception as e:
self.logger.error(f"网格 {grid_id} 转换失败: {str(e)}")
-
- # 在所有网格处理完成后创建总的metadata.xml
- self._create_merged_metadata()
- def _convert_single_grid(self, grid_id):
+ self._create_merged_metadata(tile_infos)
+
+ def _convert_single_grid(self, grid_id, grid_points):
"""转换单个网格的OBJ文件"""
# 1. 构建相关路径
grid_name = f"grid_{grid_id[0]}_{grid_id[1]}"
@@ -40,9 +42,24 @@ class ConvertOBJ:
self.logger.info(f"开始转换网格 {grid_id} 的OBJ文件")
output_osgb = os.path.join(texturing_dir, "Tile.osgb")
+ # 计算当前网格相对于中心点的偏移
+ grid_data = grid_points[grid_id]
+ lats = [point['lat'] for point in grid_data]
+ lons = [point['lon'] for point in grid_data]
+
+ min_lat = min(lats)
+ min_lon = min(lons)
+
+ # 计算偏移量(米)
+ offset_x = self._calculate_distance(self.center_lat, self.center_lon, self.center_lat, min_lon)
+ offset_y = self._calculate_distance(self.center_lat, self.center_lon, min_lat, self.center_lon)
+
+ # 修改转换命令,使用正确的参数格式
cmd = (
- f"osgconv --compressed --smooth --fix-transparency -o 0,1,0-0,0,-1 "
- f"{obj_file} {output_osgb}"
+ f"osgconv {obj_file} {output_osgb} "
+ f"--compressed --smooth --fix-transparency "
+ f"-t {offset_x},{offset_y},0 " # 使用 -t 参数进行平移
+ f"-o 0,1,0-0,0,-1"
)
try:
@@ -65,20 +82,82 @@ class ConvertOBJ:
target_osgb = os.path.join(tile_dir, f"Tile_{grid_id[0]}_{grid_id[1]}.osgb")
shutil.copy2(output_osgb, target_osgb)
- self.logger.info(f"网格 {grid_id} 转换完成")
+ # 计算当前网格的边界框
+ grid_data = grid_points[grid_id]
+ # 假设grid_data是一个列表,每个元素都是包含lat和lon的字典
+ lats = [point['lat'] for point in grid_data]
+ lons = [point['lon'] for point in grid_data]
+
+ min_lat = min(lats)
+ max_lat = max(lats)
+ min_lon = min(lons)
+ max_lon = max(lons)
+
+ # 计算相对于中心点的偏移
+ offset_x = self._calculate_distance(self.center_lat, self.center_lon, self.center_lat, min_lon)
+ offset_y = self._calculate_distance(self.center_lat, self.center_lon, min_lat, self.center_lon)
+
+ tile_info = {
+ 'id': f"{grid_id[0]}_{grid_id[1]}",
+ 'bounds': {
+ 'min_lat': min_lat,
+ 'max_lat': max_lat,
+ 'min_lon': min_lon,
+ 'max_lon': max_lon
+ },
+ 'offset': (offset_x, offset_y)
+ }
+ return tile_info
- def _create_merged_metadata(self):
+ def _calculate_distance(self, lat1, lon1, lat2, lon2):
+ """计算两点间的距离(米)"""
+ from math import sin, cos, sqrt, atan2, radians
+ R = 6371000 # 地球半径(米)
+
+ lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
+ dlat = lat2 - lat1
+ dlon = lon2 - lon1
+
+ a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
+ c = 2 * atan2(sqrt(a), sqrt(1-a))
+ return R * c
+
+ def _create_merged_metadata(self, tile_infos):
"""创建合并后的metadata.xml文件"""
metadata_content = f"""
-
EPSG:4326
-
{self.center_lon},{self.center_lat},0.000000
-
- Visible
-
-"""
+
+
+
+ {min([t['bounds']['min_lat'] for t in tile_infos])}
+ {max([t['bounds']['max_lat'] for t in tile_infos])}
+ {min([t['bounds']['min_lon'] for t in tile_infos])}
+ {max([t['bounds']['max_lon'] for t in tile_infos])}
+
+ """
+
+ for tile in tile_infos:
+ metadata_content += f"""
+
+ {tile['offset'][0]},{tile['offset'][1]},0
+
+ {tile['bounds']['min_lat']}
+ {tile['bounds']['max_lat']}
+ {tile['bounds']['min_lon']}
+ {tile['bounds']['max_lon']}
+
+ """
+
+ metadata_content += """
+
+
+
+
+ Visible
+
+ """
metadata_file = os.path.join(self.output_dir, "osgb", "metadata.xml")
with open(metadata_file, 'w', encoding='utf-8') as f: