| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import numpy as np
- import open3d as o3d
- import os
- import time
- import json
- import argparse
- def save_point_cloud_by_class(coords_file, preds_file, classes_to_show, save_pcd_path):
- """
- 加载点云坐标和预测类别,筛选指定类别,并保存为.ply文件。
- """
- # 1. 定义类别名称和颜色映射
- CLASS_NAMES = [
- 'refrigerator', 'desk', 'curtain', 'sofa', 'bookshelf', 'bed',
- 'table', 'window', 'cabinet', 'door', 'chair', 'floor', 'wall',
- 'sink', 'toilet', 'bathtub', 'shower curtain', 'picture', 'counter'
- ]
- COLOR_MAP = np.array([
- [174, 199, 232], [255, 127, 14], [152, 223, 138], [214, 39, 40],
- [148, 103, 189], [255, 187, 120], [140, 86, 75], [152, 223, 138],
- [152, 223, 138], [152, 223, 138], [196, 156, 148], [127, 127, 127],
- [152, 223, 138], [188, 189, 34], [219, 219, 141], [227, 119, 194],
- [31, 119, 180], [255, 152, 150], [82, 84, 163]
- ])
- # 2. 加载数据
- try:
- print(f"正在加载坐标文件: {coords_file}")
- coords = np.load(coords_file)
- print(f"正在加载预测文件: {preds_file}")
- predictions = np.load(preds_file)
- except FileNotFoundError as e:
- print(f"错误: 找不到文件 {e.filename}。请确保文件路径正确。")
- return
- print(f"原始点云数量: {len(coords)}")
- if len(coords) != len(predictions):
- print("警告: 坐标点数和预测标签数不匹配!")
- return
- # 3. 根据 'classes_to_show' 筛选点云
- if isinstance(classes_to_show, str):
- target_classes = [classes_to_show]
- elif isinstance(classes_to_show, list):
- target_classes = classes_to_show
- else:
- print("错误: 'classes_to_show' 参数必须是字符串或列表。")
- return
- target_indices = [CLASS_NAMES.index(cn) for cn in target_classes if cn in CLASS_NAMES]
- if not target_indices:
- print(f"错误: 类别 '{classes_to_show}' 无效或未在 CLASS_NAMES 中找到。")
- return
- print(f"正在筛选类别: {[CLASS_NAMES[i] for i in target_indices]}")
- mask = np.isin(predictions, target_indices)
- coords = coords[mask]
- predictions = predictions[mask]
- if coords.shape[0] == 0:
- print(f"警告: 在场景中没有找到属于类别 {target_classes} 的点。")
- return
- print(f"筛选后剩余点云数量: {len(coords)}")
- # 4. 创建Open3D点云对象
- pcd = o3d.geometry.PointCloud()
- pcd.points = o3d.utility.Vector3dVector(coords)
- pcd.colors = o3d.utility.Vector3dVector(COLOR_MAP[predictions] / 255.0)
- # 5. 保存筛选后的点云
- if not save_pcd_path:
- print("警告: 未提供 'save_pcd_path',不保存文件。")
- return
- print(f"正在保存筛选后的点云到: {save_pcd_path}")
- try:
- o3d.io.write_point_cloud(save_pcd_path, pcd, write_ascii=True)
- print("保存成功。")
- except Exception as e:
- print(f"错误: 保存点云文件失败: {e}")
- if __name__ == "__main__":
- parser = argparse.ArgumentParser(
- description="输入单个场景文件夹用于结果点云保存",
- formatter_class=argparse.RawTextHelpFormatter
- )
- parser.add_argument(
- '-i',
- '--input_folder',
- type=str,
- required=True,
- help='指定输入场景的文件夹路径。'
- )
- args = parser.parse_args()
- scene_folder = args.input_folder
- scenece = os.path.basename(scene_folder)
- coords_file = os.path.join(scene_folder, 'scene/val/process_data/coord.npy')
- preds_file = os.path.join(scene_folder, 'output/pred.npy')
- output_dir = os.path.join(scene_folder, 'wall_ply')
- os.makedirs(output_dir, exist_ok=True)
- print(f"\n--- 正在处理场景: {scenece} ---")
- save_point_cloud_by_class(
- coords_file=coords_file,
- preds_file=preds_file,
- classes_to_show=['wall', 'window', 'door', 'cabinet'],
- save_pcd_path=f'{output_dir}/wall_instances.ply'
- )
|