合并ply和obj代码
This commit is contained in:
parent
28126bc3be
commit
f08584d13a
@ -18,6 +18,8 @@ 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
|
||||
from post_pro.merge_obj import MergeObj
|
||||
from post_pro.merge_ply import MergePly
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -228,63 +230,22 @@ class ImagePreprocessor:
|
||||
self.logger.info(f"网格 {grid_idx + 1} 包含 {len(points)} 张图像")
|
||||
|
||||
def merge_tif(self, grid_points: Dict[int, pd.DataFrame]):
|
||||
"""合并所有网格的TIF影像"""
|
||||
self.logger.info("开始合并TIF影像")
|
||||
"""合并所有网格的影像产品"""
|
||||
self.logger.info("开始合并所有影像产品")
|
||||
merger = MergeTif(self.config.output_dir)
|
||||
merger.merge_all_tifs(grid_points)
|
||||
|
||||
# 检查是否有多个网格需要合并
|
||||
if len(grid_points) < 2:
|
||||
self.logger.info("只有一个网格,无需合并TIF影像")
|
||||
return
|
||||
def merge_obj(self, grid_points: Dict[int, pd.DataFrame]):
|
||||
"""合并所有网格的OBJ模型"""
|
||||
self.logger.info("开始合并OBJ模型")
|
||||
merger = MergeObj(self.config.output_dir)
|
||||
merger.merge_grid_obj(grid_points)
|
||||
|
||||
input_tif1, input_tif2 = None, None
|
||||
merge_count = 0
|
||||
|
||||
try:
|
||||
for grid_idx, points in grid_points.items():
|
||||
grid_tif = os.path.join(
|
||||
self.config.output_dir,
|
||||
f"grid_{grid_idx + 1}",
|
||||
"project",
|
||||
"odm_orthophoto",
|
||||
"odm_orthophoto.original.tif"
|
||||
)
|
||||
|
||||
# 检查TIF文件是否存在
|
||||
if not os.path.exists(grid_tif):
|
||||
self.logger.error(
|
||||
f"网格 {grid_idx + 1} 的TIF文件不存在: {grid_tif}")
|
||||
continue
|
||||
|
||||
if input_tif1 is None:
|
||||
input_tif1 = grid_tif
|
||||
self.logger.info(f"设置第一个输入TIF: {input_tif1}")
|
||||
else:
|
||||
input_tif2 = grid_tif
|
||||
output_tif = os.path.join(
|
||||
self.config.output_dir, "merged_orthophoto.tif")
|
||||
|
||||
self.logger.info(
|
||||
f"开始合并第 {merge_count + 1} 次:\n"
|
||||
f"输入1: {input_tif1}\n"
|
||||
f"输入2: {input_tif2}\n"
|
||||
f"输出: {output_tif}"
|
||||
)
|
||||
|
||||
merge_tif = MergeTif(input_tif1, input_tif2, output_tif)
|
||||
merge_tif.merge()
|
||||
merge_count += 1
|
||||
|
||||
input_tif1 = output_tif
|
||||
input_tif2 = None
|
||||
|
||||
self.logger.info(
|
||||
f"TIF影像合并完成,共执行 {merge_count} 次合并,"
|
||||
f"最终输出文件: {input_tif1}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"TIF影像合并过程中发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
||||
def merge_ply(self, grid_points: Dict[int, pd.DataFrame]):
|
||||
"""合并所有网格的PLY点云"""
|
||||
self.logger.info("开始合并PLY点云")
|
||||
merger = MergePly(self.config.output_dir)
|
||||
merger.merge_grid_ply(grid_points)
|
||||
|
||||
def process(self):
|
||||
"""执行完整的预处理流程"""
|
||||
@ -297,19 +258,10 @@ class ImagePreprocessor:
|
||||
self.copy_images(grid_points)
|
||||
self.logger.info("预处理任务完成")
|
||||
|
||||
# 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)
|
||||
self.merge_obj(grid_points)
|
||||
self.merge_ply(grid_points)
|
||||
except Exception as e:
|
||||
self.logger.error(f"处理过程中发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
||||
@ -318,8 +270,8 @@ class ImagePreprocessor:
|
||||
if __name__ == "__main__":
|
||||
# 创建配置
|
||||
config = PreprocessConfig(
|
||||
image_dir=r"G:\error_data\20241104140457\code\images",
|
||||
output_dir=r"G:\ODM_output\20241104140457",
|
||||
image_dir=r"E:\datasets\UAV\1009\project\images",
|
||||
output_dir=r"G:\ODM_output\1009",
|
||||
|
||||
cluster_eps=0.01,
|
||||
cluster_min_samples=5,
|
||||
@ -335,11 +287,11 @@ if __name__ == "__main__":
|
||||
filter_dense_distance_threshold=10,
|
||||
filter_time_threshold=timedelta(minutes=5),
|
||||
|
||||
grid_size=1000,
|
||||
grid_size=300,
|
||||
grid_overlap=0.03,
|
||||
|
||||
|
||||
mode="快拼模式",
|
||||
mode="重建模式",
|
||||
)
|
||||
|
||||
# 创建处理器并执行
|
||||
|
109
post_pro/merge_obj.py
Normal file
109
post_pro/merge_obj.py
Normal file
@ -0,0 +1,109 @@
|
||||
import os
|
||||
import logging
|
||||
import numpy as np
|
||||
from typing import Dict
|
||||
import pandas as pd
|
||||
import open3d as o3d
|
||||
|
||||
|
||||
class MergeObj:
|
||||
def __init__(self, output_dir: str):
|
||||
self.output_dir = output_dir
|
||||
self.logger = logging.getLogger('UAV_Preprocess.MergeObj')
|
||||
|
||||
def merge_two_objs(self, obj1_path: str, obj2_path: str, output_path: str):
|
||||
"""使用Open3D合并两个OBJ文件"""
|
||||
try:
|
||||
self.logger.info("开始合并OBJ模型")
|
||||
self.logger.info(f"输入模型1: {obj1_path}")
|
||||
self.logger.info(f"输入模型2: {obj2_path}")
|
||||
self.logger.info(f"输出模型: {output_path}")
|
||||
|
||||
# 检查输入文件是否存在
|
||||
if not os.path.exists(obj1_path) or not os.path.exists(obj2_path):
|
||||
raise FileNotFoundError("输入模型文件不存在")
|
||||
|
||||
# 读取OBJ文件
|
||||
mesh1 = o3d.io.read_triangle_mesh(obj1_path)
|
||||
mesh2 = o3d.io.read_triangle_mesh(obj2_path)
|
||||
|
||||
if mesh1.is_empty() or mesh2.is_empty():
|
||||
raise ValueError("无法读取OBJ文件或文件为空")
|
||||
|
||||
# # 计算并对齐中心点
|
||||
# center1 = mesh1.get_center()
|
||||
# center2 = mesh2.get_center()
|
||||
# translation_vector = center2 - center1
|
||||
# mesh2.translate(translation_vector)
|
||||
|
||||
# 不对齐,直接合并网格
|
||||
combined_mesh = mesh1 + mesh2
|
||||
|
||||
# 优化合并后的网格
|
||||
combined_mesh.remove_duplicated_vertices()
|
||||
combined_mesh.remove_duplicated_triangles()
|
||||
combined_mesh.compute_vertex_normals()
|
||||
|
||||
# 保存合并后的模型
|
||||
if not o3d.io.write_triangle_mesh(output_path, combined_mesh):
|
||||
raise RuntimeError("保存合并后的模型失败")
|
||||
|
||||
self.logger.info(f"模型合并成功,已保存至: {output_path}")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"合并OBJ模型时发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
def merge_grid_obj(self, grid_points: Dict[int, pd.DataFrame]):
|
||||
"""合并所有网格的OBJ模型"""
|
||||
self.logger.info("开始合并所有网格的OBJ模型")
|
||||
|
||||
if len(grid_points) < 2:
|
||||
self.logger.info("只有一个网格,无需合并")
|
||||
return
|
||||
|
||||
input_obj1, input_obj2 = None, None
|
||||
merge_count = 0
|
||||
|
||||
try:
|
||||
for grid_idx, points in grid_points.items():
|
||||
grid_obj = os.path.join(
|
||||
self.output_dir,
|
||||
f"grid_{grid_idx + 1}",
|
||||
"project",
|
||||
"odm_texturing",
|
||||
"odm_textured_model_geo.obj"
|
||||
)
|
||||
|
||||
if not os.path.exists(grid_obj):
|
||||
self.logger.warning(f"网格 {grid_idx + 1} 的OBJ文件不存在: {grid_obj}")
|
||||
continue
|
||||
|
||||
if input_obj1 is None:
|
||||
input_obj1 = grid_obj
|
||||
self.logger.info(f"设置第一个输入OBJ: {input_obj1}")
|
||||
else:
|
||||
input_obj2 = grid_obj
|
||||
output_obj = os.path.join(self.output_dir, "merged_model.obj")
|
||||
|
||||
self.logger.info(
|
||||
f"开始合并第 {merge_count + 1} 次:\n"
|
||||
f"输入1: {input_obj1}\n"
|
||||
f"输入2: {input_obj2}\n"
|
||||
f"输出: {output_obj}"
|
||||
)
|
||||
|
||||
self.merge_two_objs(input_obj1, input_obj2, output_obj)
|
||||
merge_count += 1
|
||||
|
||||
input_obj1 = output_obj
|
||||
input_obj2 = None
|
||||
|
||||
self.logger.info(
|
||||
f"OBJ模型合并完成,共执行 {merge_count} 次合并,"
|
||||
f"最终输出文件: {input_obj1}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"OBJ模型合并过程中发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
108
post_pro/merge_ply.py
Normal file
108
post_pro/merge_ply.py
Normal file
@ -0,0 +1,108 @@
|
||||
import os
|
||||
import logging
|
||||
import numpy as np
|
||||
from typing import Dict
|
||||
import pandas as pd
|
||||
import open3d as o3d
|
||||
|
||||
|
||||
class MergePly:
|
||||
def __init__(self, output_dir: str):
|
||||
self.output_dir = output_dir
|
||||
self.logger = logging.getLogger('UAV_Preprocess.MergePly')
|
||||
|
||||
def merge_two_plys(self, ply1_path: str, ply2_path: str, output_path: str):
|
||||
"""合并两个PLY文件"""
|
||||
try:
|
||||
self.logger.info("开始合并PLY点云")
|
||||
self.logger.info(f"输入点云1: {ply1_path}")
|
||||
self.logger.info(f"输入点云2: {ply2_path}")
|
||||
self.logger.info(f"输出点云: {output_path}")
|
||||
|
||||
# 检查输入文件是否存在
|
||||
if not os.path.exists(ply1_path) or not os.path.exists(ply2_path):
|
||||
raise FileNotFoundError("输入点云文件不存在")
|
||||
|
||||
# 读取点云
|
||||
pcd1 = o3d.io.read_point_cloud(ply1_path)
|
||||
pcd2 = o3d.io.read_point_cloud(ply2_path)
|
||||
|
||||
if pcd1 is None or pcd2 is None:
|
||||
raise ValueError("无法读取点云文件")
|
||||
|
||||
# 获取点云中心
|
||||
center1 = pcd1.get_center()
|
||||
center2 = pcd2.get_center()
|
||||
|
||||
# 计算平移向量
|
||||
translation_vector = center2 - center1
|
||||
|
||||
# 对齐点云
|
||||
pcd2.translate(translation_vector)
|
||||
|
||||
# 合并点云
|
||||
combined_pcd = pcd1 + pcd2
|
||||
|
||||
# 保存合并后的点云
|
||||
if not o3d.io.write_point_cloud(output_path, combined_pcd):
|
||||
raise RuntimeError("保存合并后的点云失败")
|
||||
|
||||
self.logger.info(f"点云合并成功,已保存至: {output_path}")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"合并PLY点云时发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
def merge_grid_ply(self, grid_points: Dict[int, pd.DataFrame]):
|
||||
"""合并所有网格的PLY点云"""
|
||||
self.logger.info("开始合并所有网格的PLY点云")
|
||||
|
||||
if len(grid_points) < 2:
|
||||
self.logger.info("只有一个网格,无需合并")
|
||||
return
|
||||
|
||||
input_ply1, input_ply2 = None, None
|
||||
merge_count = 0
|
||||
|
||||
try:
|
||||
for grid_idx, points in grid_points.items():
|
||||
grid_ply = os.path.join(
|
||||
self.output_dir,
|
||||
f"grid_{grid_idx + 1}",
|
||||
"project",
|
||||
"odm_georeferencing",
|
||||
"odm_georeferenced_model.ply"
|
||||
)
|
||||
|
||||
if not os.path.exists(grid_ply):
|
||||
self.logger.warning(f"网格 {grid_idx + 1} 的PLY文件不存在: {grid_ply}")
|
||||
continue
|
||||
|
||||
if input_ply1 is None:
|
||||
input_ply1 = grid_ply
|
||||
self.logger.info(f"设置第一个输入PLY: {input_ply1}")
|
||||
else:
|
||||
input_ply2 = grid_ply
|
||||
output_ply = os.path.join(self.output_dir, "merged_pointcloud.ply")
|
||||
|
||||
self.logger.info(
|
||||
f"开始合并第 {merge_count + 1} 次:\n"
|
||||
f"输入1: {input_ply1}\n"
|
||||
f"输入2: {input_ply2}\n"
|
||||
f"输出: {output_ply}"
|
||||
)
|
||||
|
||||
self.merge_two_plys(input_ply1, input_ply2, output_ply)
|
||||
merge_count += 1
|
||||
|
||||
input_ply1 = output_ply
|
||||
input_ply2 = None
|
||||
|
||||
self.logger.info(
|
||||
f"PLY点云合并完成,共执行 {merge_count} 次合并,"
|
||||
f"最终输出文件: {input_ply1}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"PLY点云合并过程中发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
@ -1,34 +1,33 @@
|
||||
from osgeo import gdal
|
||||
import logging
|
||||
import os
|
||||
from typing import Dict
|
||||
import pandas as pd
|
||||
import sys
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
|
||||
class MergeTif:
|
||||
def __init__(self, input_tif1, input_tif2, output_tif):
|
||||
self.input_tif1 = input_tif1
|
||||
self.input_tif2 = input_tif2
|
||||
self.output_tif = output_tif
|
||||
def __init__(self, output_dir: str):
|
||||
self.output_dir = output_dir
|
||||
self.logger = logging.getLogger('UAV_Preprocess.MergeTif')
|
||||
|
||||
def merge(self):
|
||||
def merge_two_tifs(self, input_tif1: str, input_tif2: str, output_tif: str):
|
||||
"""合并两张TIF影像"""
|
||||
try:
|
||||
self.logger.info("开始合并TIF影像")
|
||||
self.logger.info(f"输入影像1: {self.input_tif1}")
|
||||
self.logger.info(f"输入影像2: {self.input_tif2}")
|
||||
self.logger.info(f"输出影像: {self.output_tif}")
|
||||
self.logger.info(f"输入影像1: {input_tif1}")
|
||||
self.logger.info(f"输入影像2: {input_tif2}")
|
||||
self.logger.info(f"输出影像: {output_tif}")
|
||||
|
||||
# 检查输入文件是否存在
|
||||
if not os.path.exists(self.input_tif1) or not os.path.exists(self.input_tif2):
|
||||
if not os.path.exists(input_tif1) or not os.path.exists(input_tif2):
|
||||
error_msg = "输入影像文件不存在"
|
||||
self.logger.error(error_msg)
|
||||
raise FileNotFoundError(error_msg)
|
||||
|
||||
# 打开影像,检查投影是否一致
|
||||
datasets = [gdal.Open(tif)
|
||||
for tif in [self.input_tif1, self.input_tif2]]
|
||||
datasets = [gdal.Open(tif) for tif in [input_tif1, input_tif2]]
|
||||
if None in datasets:
|
||||
error_msg = "无法打开输入影像文件"
|
||||
self.logger.error(error_msg)
|
||||
@ -47,20 +46,14 @@ class MergeTif:
|
||||
# 创建 GDAL Warp 选项
|
||||
warp_options = gdal.WarpOptions(
|
||||
format="GTiff",
|
||||
resampleAlg="average", # 设置重采样方法为平均值
|
||||
srcNodata=0, # 输入影像中的无效值
|
||||
dstNodata=0, # 输出影像中的无效值
|
||||
multithread=True # 启用多线程优化
|
||||
resampleAlg="average",
|
||||
srcNodata=0,
|
||||
dstNodata=0,
|
||||
multithread=True
|
||||
)
|
||||
|
||||
self.logger.info("开始执行影像拼接...")
|
||||
|
||||
# 使用 GDAL 的 Warp 方法进行拼接
|
||||
result = gdal.Warp(
|
||||
self.output_tif,
|
||||
[self.input_tif1, self.input_tif2], # 输入多张影像
|
||||
options=warp_options
|
||||
)
|
||||
result = gdal.Warp(output_tif, [input_tif1, input_tif2], options=warp_options)
|
||||
|
||||
if result is None:
|
||||
error_msg = "影像拼接失败"
|
||||
@ -68,19 +61,109 @@ class MergeTif:
|
||||
raise RuntimeError(error_msg)
|
||||
|
||||
# 获取输出影像的基本信息
|
||||
output_dataset = gdal.Open(self.output_tif)
|
||||
output_dataset = gdal.Open(output_tif)
|
||||
if output_dataset:
|
||||
width = output_dataset.RasterXSize
|
||||
height = output_dataset.RasterYSize
|
||||
bands = output_dataset.RasterCount
|
||||
self.logger.info(f"拼接完成,输出影像大小: {width}x{height},波段数: {bands}")
|
||||
|
||||
self.logger.info(f"影像拼接成功,输出文件保存至: {self.output_tif}")
|
||||
self.logger.info(f"影像拼接成功,输出文件保存至: {output_tif}")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"影像拼接过程中发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
def merge_grid_tif(self, grid_points: Dict[int, pd.DataFrame], product_info: dict):
|
||||
"""合并指定产品的所有网格"""
|
||||
product_name = product_info['name']
|
||||
product_path = product_info['path']
|
||||
filename = product_info['filename']
|
||||
|
||||
self.logger.info(f"开始合并{product_name}")
|
||||
|
||||
if len(grid_points) < 2:
|
||||
self.logger.info("只有一个网格,无需合并")
|
||||
return
|
||||
|
||||
input_tif1, input_tif2 = None, None
|
||||
merge_count = 0
|
||||
|
||||
try:
|
||||
for grid_idx, points in grid_points.items():
|
||||
grid_tif = os.path.join(
|
||||
self.output_dir,
|
||||
f"grid_{grid_idx + 1}",
|
||||
"project",
|
||||
product_path,
|
||||
filename
|
||||
)
|
||||
|
||||
if not os.path.exists(grid_tif):
|
||||
self.logger.warning(f"网格 {grid_idx + 1} 的{product_name}不存在: {grid_tif}")
|
||||
continue
|
||||
|
||||
if input_tif1 is None:
|
||||
input_tif1 = grid_tif
|
||||
self.logger.info(f"设置第一个输入{product_name}: {input_tif1}")
|
||||
else:
|
||||
input_tif2 = grid_tif
|
||||
output_tif = os.path.join(self.output_dir, f"merged_{product_info['output']}")
|
||||
|
||||
self.logger.info(
|
||||
f"开始合并{product_name}第 {merge_count + 1} 次:\n"
|
||||
f"输入1: {input_tif1}\n"
|
||||
f"输入2: {input_tif2}\n"
|
||||
f"输出: {output_tif}"
|
||||
)
|
||||
|
||||
self.merge_two_tifs(input_tif1, input_tif2, output_tif)
|
||||
merge_count += 1
|
||||
|
||||
input_tif1 = output_tif
|
||||
input_tif2 = None
|
||||
|
||||
self.logger.info(
|
||||
f"{product_name}合并完成,共执行 {merge_count} 次合并,"
|
||||
f"最终输出文件: {input_tif1}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"{product_name}合并过程中发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
def merge_all_tifs(self, grid_points: Dict[int, pd.DataFrame]):
|
||||
"""合并所有产品(正射影像、DSM和DTM)"""
|
||||
try:
|
||||
products = [
|
||||
{
|
||||
'name': '正射影像',
|
||||
'path': 'odm_orthophoto',
|
||||
'filename': 'odm_orthophoto.original.tif',
|
||||
'output': 'orthophoto.tif'
|
||||
},
|
||||
{
|
||||
'name': 'DSM',
|
||||
'path': 'odm_dem',
|
||||
'filename': 'dsm.original.tif',
|
||||
'output': 'dsm.tif'
|
||||
},
|
||||
{
|
||||
'name': 'DTM',
|
||||
'path': 'odm_dem',
|
||||
'filename': 'dtm.original.tif',
|
||||
'output': 'dtm.tif'
|
||||
}
|
||||
]
|
||||
|
||||
for product in products:
|
||||
self.merge_grid_product(grid_points, product)
|
||||
|
||||
self.logger.info("所有产品合并完成")
|
||||
except Exception as e:
|
||||
self.logger.error(f"产品合并过程中发生错误: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from utils.logger import setup_logger
|
||||
@ -95,5 +178,5 @@ if __name__ == "__main__":
|
||||
setup_logger(output_dir)
|
||||
|
||||
# 执行拼接
|
||||
merge_tif = MergeTif(input_tif1, input_tif2, output_tif)
|
||||
merge_tif.merge()
|
||||
merge_tif = MergeTif(output_dir)
|
||||
merge_tif.merge_two_tifs(input_tif1, input_tif2, output_tif)
|
||||
|
@ -6,3 +6,4 @@ piexif
|
||||
geopy
|
||||
psutil
|
||||
docker>=6.1.3
|
||||
open3d
|
||||
|
34
tools/merge_obj.py
Normal file
34
tools/merge_obj.py
Normal file
@ -0,0 +1,34 @@
|
||||
import open3d as o3d
|
||||
import numpy as np
|
||||
|
||||
# 读取 .obj 文件
|
||||
def load_obj(file_path):
|
||||
mesh = o3d.io.read_triangle_mesh(file_path)
|
||||
if not mesh.is_empty():
|
||||
return mesh
|
||||
else:
|
||||
raise ValueError(f"Failed to load {file_path}")
|
||||
|
||||
# 合并两个网格
|
||||
def merge_meshes(mesh1, mesh2):
|
||||
# 直接合并网格
|
||||
combined_mesh = mesh1 + mesh2
|
||||
return combined_mesh
|
||||
|
||||
# 保存合并后的网格
|
||||
def save_merged_mesh(mesh, output_path):
|
||||
o3d.io.write_triangle_mesh(output_path, mesh)
|
||||
print(f"Saved merged mesh to {output_path}")
|
||||
|
||||
# 示例用法
|
||||
mesh1 = load_obj("model1.obj")
|
||||
mesh2 = load_obj("model2.obj")
|
||||
|
||||
# 合并两个网格
|
||||
merged_mesh = merge_meshes(mesh1, mesh2)
|
||||
|
||||
# 保存合并后的网格
|
||||
save_merged_mesh(merged_mesh, "merged_model.obj")
|
||||
|
||||
# 可视化合并后的网格
|
||||
o3d.visualization.draw_geometries([merged_mesh])
|
22
tools/merge_ply.py
Normal file
22
tools/merge_ply.py
Normal file
@ -0,0 +1,22 @@
|
||||
import open3d as o3d
|
||||
import numpy as np
|
||||
|
||||
# 读取第一个PLY文件
|
||||
pcd1 = o3d.io.read_point_cloud("path_to_first_file.ply")
|
||||
|
||||
# 读取第二个PLY文件
|
||||
pcd2 = o3d.io.read_point_cloud("path_to_second_file.ply")
|
||||
|
||||
# 可选:如果需要调整坐标系,可以通过平移、旋转来对齐点云
|
||||
# 例如,平移第二个点云
|
||||
offset = np.array([1000, 2000, 3000])
|
||||
pcd2.translate(offset)
|
||||
|
||||
# 合并点云
|
||||
combined_pcd = pcd1 + pcd2
|
||||
|
||||
# 保存合并后的点云为PLY文件
|
||||
o3d.io.write_point_cloud("merged_output.ply", combined_pcd)
|
||||
|
||||
# 可视化
|
||||
o3d.visualization.draw_geometries([combined_pcd])
|
Loading…
Reference in New Issue
Block a user