结果后处理修改

This commit is contained in:
龙澳 2025-01-09 11:45:55 +08:00
parent 40fad13aca
commit cd36dcb6e9
5 changed files with 125 additions and 21 deletions

50
main.py Normal file
View File

@ -0,0 +1,50 @@
import argparse
from datetime import timedelta
from odm_preprocess import PreprocessConfig, ImagePreprocessor
def parse_args():
parser = argparse.ArgumentParser(description='ODM预处理工具')
# 必需参数
parser.add_argument('--image_dir', required=True, help='输入图片目录路径')
parser.add_argument('--output_dir', required=True, help='输出目录路径')
# 可选参数
parser.add_argument('--mode', default='重建模式', choices=['快拼模式', '三维模式', '重建模式'], help='处理模式')
parser.add_argument('--grid_size', type=float, default=1000, help='网格大小(米)')
parser.add_argument('--grid_overlap', type=float, default=0.05, help='网格重叠率')
parser.add_argument('--produce_dem', action='store_true', help='是否生成DEM')
args = parser.parse_args()
return args
def main():
args = parse_args()
# 创建配置
config = PreprocessConfig(
image_dir=args.image_dir,
output_dir=args.output_dir,
mode=args.mode,
grid_size=args.grid_size,
grid_overlap=args.grid_overlap,
produce_dem=args.produce_dem,
# 其他参数使用默认值
cluster_eps=0.01,
cluster_min_samples=5,
time_group_overlap_threshold=0.7,
time_group_interval=timedelta(minutes=5),
filter_distance_threshold=0.001,
filter_min_neighbors=6,
filter_grid_size=0.001,
filter_dense_distance_threshold=10,
filter_time_threshold=timedelta(minutes=5),
)
# 创建处理器并执行
processor = ImagePreprocessor(config)
processor.process()
if __name__ == '__main__':
main()

View File

@ -247,17 +247,68 @@ class ImagePreprocessor:
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]):
"""后处理:合并或复制处理结果"""
if len(successful_grid_points) == 1:
self.logger.info(f"只有一个网格{successful_grid_points.keys()},无需合并")
self.logger.info(f"生产结果请在{successful_grid_points.keys()[0]}目录下查看")
# 获取唯一成功的网格ID
grid_id = list(successful_grid_points.keys())[0]
self.logger.info(f"只有一个网格 {grid_id} 成功处理,直接复制结果")
# 构建源目录路径(成功网格的输出目录)
src_dir = os.path.join(
self.config.output_dir, f"grid_{grid_id[0]}_{grid_id[1]}", "project")
# 复制正射影像
if self.config.mode == "快拼模式":
shutil.copy2(os.path.join(src_dir, "odm_orthophoto", "odm_orthophoto.original.tif"),
os.path.join(self.config.output_dir,
"orthophoto.tif")
)
elif self.config.mode == "三维模式":
shutil.copy2(os.path.join(src_dir, "odm_georeferencing", "odm_georeferenced_model.laz"),
os.path.join(self.config.output_dir,
"pointcloud.laz")
)
shutil.copytree(os.path.join(src_dir, "odm_texturing"),
os.path.join(self.config.output_dir, "texturing"))
elif self.config.mode == "重建模式":
shutil.copy2(os.path.join(src_dir, "odm_orthophoto", "odm_orthophoto.tif"),
os.path.join(self.config.output_dir,
"orthophoto.tif")
)
shutil.copy2(os.path.join(src_dir, "odm_georeferencing", "odm_georeferenced_model.laz"),
os.path.join(self.config.output_dir,
"odm_georeferenced_model.laz")
)
shutil.copytree(os.path.join(src_dir, "odm_texturing"),
os.path.join(self.config.output_dir, "texturing"))
if self.config.produce_dem:
shutil.copy2(
os.path.join(src_dir, "odm_dem", "dsm.tif"),
os.path.join(self.config.output_dir, "dsm.tif")
)
shutil.copy2(
os.path.join(src_dir, "odm_dem", "dtm.tif"),
os.path.join(self.config.output_dir, "dtm.tif")
)
self.logger.info("单网格结果复制完成")
return
# 如果有多个网格,执行合并操作
elif len(successful_grid_points) < len(grid_points):
self.logger.warning(
f"{len(grid_points) - len(successful_grid_points)} 个网格处理失败,"
f"将只合并成功处理的 {len(successful_grid_points)} 个网格"
)
self.merge_tif(successful_grid_points, self.config.produce_dem)
if self.config.mode != "快拼模式":
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)
else:
self.merge_tif(successful_grid_points, self.config.produce_dem)
self.merge_ply(successful_grid_points)
self.merge_obj(successful_grid_points, translations)
@ -286,8 +337,8 @@ class ImagePreprocessor:
if __name__ == "__main__":
# 创建配置
config = PreprocessConfig(
image_dir=r"G:\test_data\error1_L",
output_dir=r"G:\ODM_output\error1_L",
image_dir=r"E:\datasets\UAV\134\project\images",
output_dir=r"G:\ODM_output\134",
cluster_eps=0.01,
cluster_min_samples=5,
@ -307,7 +358,7 @@ if __name__ == "__main__":
grid_overlap=0.05,
mode="重建模式",
mode="快拼模式",
produce_dem=False,
)

View File

@ -35,7 +35,7 @@ class MergePly:
kwargs = {
'all_inputs': " ".join(laz_files),
'output': os.path.join(self.output_dir, 'merged_pointcloud.laz')
'output': os.path.join(self.output_dir, 'pointcloud.laz')
}
subprocess.run('D:\\software\\LAStools\\bin\\lasmerge64.exe -i {all_inputs} -o "{output}"'.format(**kwargs))

View File

@ -175,7 +175,7 @@ class MergeObj:
all_face_materials.append(material_map2.get(material))
# 写入合并后的obj文件使用与MTL文件相同的名称
mtl_filename = "merged_model.mtl" # 使用固定的MTL文件名
mtl_filename = "textured_model.mtl" # 使用固定的MTL文件名
self.write_obj(output_path, all_vertices, all_tex_coords, all_normals,
all_faces, all_face_materials, mtl_filename)
self.logger.info(f"模型合并成功,已保存至: {output_path}")
@ -273,7 +273,7 @@ class MergeObj:
try:
# 创建输出目录
output_model_dir = os.path.join(self.output_dir, "merged_model")
output_model_dir = os.path.join(self.output_dir, "texturing")
os.makedirs(output_model_dir, exist_ok=True)
# 获取所有有效的网格文件
@ -323,7 +323,7 @@ class MergeObj:
all_materials.update(updated_materials)
# 写入合并后的MTL文件
final_mtl = os.path.join(output_model_dir, "merged_model.mtl")
final_mtl = os.path.join(output_model_dir, "textured_model.mtl")
with open(final_mtl, 'w') as f:
for mat_name, content in all_materials.items():
f.write(f"newmtl {mat_name}\n")
@ -353,7 +353,7 @@ class MergeObj:
merged_obj = temp_output
# 最终结果
final_obj = os.path.join(output_model_dir, "merged_model.obj")
final_obj = os.path.join(output_model_dir, "textured_model.obj")
try:
if os.path.exists(final_obj):
os.remove(final_obj)
@ -377,8 +377,8 @@ class MergeObj:
self.logger.info(
f"模型合并完成,输出目录: {output_model_dir}\n"
f"- OBJ文件: merged_model.obj\n"
f"- MTL文件: merged_model.mtl\n"
f"- OBJ文件: textured_model.obj\n"
f"- MTL文件: textured_model.mtl\n"
f"- 纹理文件: {len(os.listdir(output_model_dir)) - 2}"
)

View File

@ -94,11 +94,11 @@ class ODMProcessMonitor:
self.logger.error(f"检查正射影像时发生错误: {str(e)}")
return False
def run_odm_with_monitor(self, grid_dir: str, grid_id: tuple, fast_mode: bool = True, produce_dem: bool = False) -> Tuple[bool, str]:
def run_odm_with_monitor(self, grid_dir: str, grid_id: tuple, produce_dem: bool = False) -> Tuple[bool, str]:
"""运行ODM命令"""
if produce_dem and fast_mode:
self.logger.error("快拼模式下无法生成DEM请调整生产参数")
return False, "快拼模式下无法生成DEM请调整生产参数"
# if produce_dem and self.mode == "快拼模式":
# self.logger.error("快拼模式下无法生成DEM请调整生产参数")
# return False, "快拼模式下无法生成DEM请调整生产参数"
self.logger.info(f"开始处理网格 ({grid_id[0]},{grid_id[1]})")
success = False
@ -136,11 +136,15 @@ class ODMProcessMonitor:
f"--dtm "
)
if fast_mode:
if self.mode == "快拼模式":
docker_command += (
f"--fast-orthophoto "
#f"--fast-orthophoto "
f"--skip-3dmodel "
)
elif self.mode == "三维模式":
docker_command += (
f"--skip-orthophoto "
)
docker_command += "--rerun-all"
self.logger.info(docker_command)
@ -224,7 +228,6 @@ class ODMProcessMonitor:
success, error_msg = self.run_odm_with_monitor(
grid_dir=grid_dir,
grid_id=grid_id,
fast_mode=(self.mode == "快拼模式"),
produce_dem=produce_dem
)