Files
worldmodel/plans/iphone/data_format_specification.md
T
gaojie 6b64d458bd
Sync to site1 / sync (push) Has been cancelled
chore: update iphone categories from worldmodel to RoomPlan
2026-05-21 02:30:30 +08:00

20 KiB
Raw Blame History

title, date, draft, tags, categories
title date draft tags categories
酒店场景建模项目 - 数据格式规范 2026-05-20 false
iPhone
3D 重建
RoomPlan
SLAM
IMU
点云
RoomPlan

酒店场景建模项目 - 数据格式规范

📋 文档概述

本文档详细定义了酒店场景数字孪生项目中所有数据的存储格式、命名规范和交换标准,确保数据的可复用性、可扩展性和跨平台兼容性。


一、数据组织结构

1.1 目录树结构

hotel_dataset/
├── metadata.json                          # 全局元数据
├── calibration/                           # 传感器标定
│   ├── camera_intrinsics.yaml
│   ├── lidar_camera_extrinsics.yaml
│   ├── imu_camera_extrinsics.yaml
│   └── calibration_report.pdf
├── scenes/                                # 场景数据
│   ├── lobby_01/                          # 大堂场景1
│   │   ├── scene_info.json                # 场景元数据
│   │   ├── raw/                           # 原始数据
│   │   │   ├── lidar/                     # LiDAR点云
│   │   │   │   ├── 0000000.pcd
│   │   │   │   ├── 0000001.pcd
│   │   │   │   └── ...
│   │   │   ├── rgb/                       # RGB图像
│   │   │   │   ├── 0000000.jpg
│   │   │   │   ├── 0000001.jpg
│   │   │   │   └── ...
│   │   │   ├── depth/                     # 深度图
│   │   │   │   ├── 0000000.png            # 16-bit PNG
│   │   │   │   ├── 0000001.png
│   │   │   │   └── ...
│   │   │   ├── imu/                       # IMU数据
│   │   │   │   └── imu_data.csv
│   │   │   ├── polarized/                 # 偏振图像(卫生间)
│   │   │   │   ├── 0deg/
│   │   │   │   ├── 45deg/
│   │   │   │   ├── 90deg/
│   │   │   │   └── 135deg/
│   │   │   └── timestamps.txt             # 时间戳对齐
│   │   ├── processed/                     # 处理后数据
│   │   │   ├── slam/                      # SLAM结果
│   │   │   │   ├── trajectory.txt         # 相机轨迹
│   │   │   │   ├── sparse_map.ply         # 稀疏点云
│   │   │   │   ├── dense_map.ply          # 稠密点云
│   │   │   │   └── loop_closures.json     # 回环信息
│   │   │   ├── colmap/                    # COLMAP输出
│   │   │   │   ├── cameras.txt
│   │   │   │   ├── images.txt
│   │   │   │   ├── points3D.txt
│   │   │   │   └── sparse/
│   │   │   ├── 3dgs/                      # 3D Gaussian Splatting
│   │   │   │   ├── point_cloud.ply        # 初始点云
│   │   │   │   ├── cameras.json           # 相机参数
│   │   │   │   ├── cfg_args              # 训练配置
│   │   │   │   ├── input.ply              # 优化后高斯
│   │   │   │   └── iteration_30000/       # 检查点
│   │   │   ├── nerf/                      # NeRF/Ref-NeRF
│   │   │   │   ├── transforms.json        # NeRF格式位姿
│   │   │   │   ├── model.pth              # 模型权重
│   │   │   │   └── config.yaml
│   │   │   ├── mesh/                      # 网格模型
│   │   │   │   ├── scene.obj              # 主网格
│   │   │   │   ├── scene.mtl              # 材质文件
│   │   │   │   ├── textures/              # 纹理贴图
│   │   │   │   │   ├── diffuse.png
│   │   │   │   │   ├── normal.png
│   │   │   │   │   └── roughness.png
│   │   │   │   └── scene_watertight.obj   # 水密网格
│   │   │   ├── semantic/                  # 语义信息
│   │   │   │   ├── detections/            # 2D检测
│   │   │   │   │   ├── yolo_results.json
│   │   │   │   │   └── sam_masks/
│   │   │   │   ├── instances_3d.json      # 3D实例
│   │   │   │   ├── scene_graph.json       # 场景图
│   │   │   │   ├── clip_features.npy      # CLIP特征
│   │   │   │   └── semantic_map.ply       # 语义点云
│   │   │   └── physics/                   # 物理属性
│   │   │       ├── scene.usd              # USD场景
│   │   │       ├── collision_meshes/      # 碰撞网格
│   │   │       ├── articulation.json      # 铰接信息
│   │   │       └── material_props.json    # 材质物理属性
│   │   └── renders/                       # 渲染结果
│   │       ├── novel_views/               # 新视角
│   │       ├── depth_maps/                # 深度图
│   │       └── semantic_maps/             # 语义图
│   ├── room_301/                          # 客房场景
│   │   └── ...(结构同上)
│   └── bathroom_301/                      # 卫生间场景
│       └── ...(结构同上)
├── annotations/                           # 人工标注(可选)
│   ├── object_labels.json
│   ├── spatial_relations.json
│   └── physics_properties.json
└── benchmarks/                            # 评测数据
    ├── test_views/                        # 测试视角
    ├── ground_truth/                      # 真值数据
    └── metrics/                           # 评测结果

1.2 命名规范

场景命名:
  格式: {scene_type}_{id}
  示例: lobby_01, room_301, bathroom_301
  
  scene_type:
    - lobby: 大堂
    - corridor: 走廊
    - room: 客房
    - bathroom: 卫生间
    - restaurant: 餐厅
    - gym: 健身房

文件命名:
  时序数据: {frame_id:07d}.{ext}
  示例: 0000000.jpg, 0000001.pcd
  
  处理结果: {descriptor}_{version}.{ext}
  示例: dense_map_v2.ply, scene_graph_final.json

版本控制:
  格式: v{major}.{minor}.{patch}
  示例: v1.0.0, v1.2.3

二、原始数据格式

2.1 点云数据(LiDAR

格式:PCDPoint Cloud Data

文件格式: ASCII 或 Binary PCD
编码: UTF-8
字段:
  - x, y, z: 坐标(float32, 单位:米)
  - intensity: 反射强度(uint8, 0-255
  - timestamp: 时间戳(float64, Unix时间)
  - ring: 激光环IDuint16, 可选)

示例文件头:
  VERSION 0.7
  FIELDS x y z intensity timestamp
  SIZE 4 4 4 1 8
  TYPE F F F U F
  COUNT 1 1 1 1 1
  WIDTH 65536
  HEIGHT 1
  VIEWPOINT 0 0 0 1 0 0 0
  POINTS 65536
  DATA binary

Python读取示例

import open3d as o3d
import numpy as np

def load_pcd(filepath):
    """加载PCD点云"""
    pcd = o3d.io.read_point_cloud(filepath)
    
    # 提取数据
    points = np.asarray(pcd.points)  # (N, 3)
    
    # 如果有颜色
    if pcd.has_colors():
        colors = np.asarray(pcd.colors)  # (N, 3)
    
    # 如果有法线
    if pcd.has_normals():
        normals = np.asarray(pcd.normals)  # (N, 3)
    
    return pcd, points

# 保存PCD
def save_pcd(filepath, points, colors=None, normals=None):
    """保存PCD点云"""
    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(points)
    
    if colors is not None:
        pcd.colors = o3d.utility.Vector3dVector(colors)
    
    if normals is not None:
        pcd.normals = o3d.utility.Vector3dVector(normals)
    
    o3d.io.write_point_cloud(filepath, pcd, write_ascii=False)

2.2 RGB图像

格式:JPEG / PNG

RGB图像:
  格式: JPEG(有损压缩)
  分辨率: 1920×1080 或更高
  色彩空间: sRGB
  质量: 95JPEG质量参数)
  命名: {frame_id:07d}.jpg

高质量纹理:
  格式: PNG(无损)
  分辨率: 4K (3840×2160) 或更高
  色彩深度: 8-bit per channel
  命名: texture_{id:04d}.png

EXIF元数据(嵌入图像):

{
  "DateTime": "2026:05:16 10:30:45",
  "Make": "Apple",
  "Model": "iPhone 15 Pro Max",
  "FocalLength": 24.0,
  "FNumber": 1.78,
  "ISO": 100,
  "ExposureTime": "1/120",
  "GPSLatitude": 31.2304,
  "GPSLongitude": 121.4737,
  "GPSAltitude": 10.5
}

2.3 深度图

格式:16-bit PNG

格式: PNG
位深度: 16-bit unsigned integer
编码: 深度值(毫米)
范围: 0-65535 mm (0-65.535米)
无效值: 0(表示无深度数据)

深度值计算:
  depth_meters = pixel_value / 1000.0
  
示例:
  pixel_value = 1500 → depth = 1.5米
  pixel_value = 0 → 无效深度

Python读取示例

import cv2
import numpy as np

def load_depth(filepath):
    """加载16-bit深度图"""
    depth_mm = cv2.imread(filepath, cv2.IMREAD_ANYDEPTH)
    depth_m = depth_mm.astype(np.float32) / 1000.0
    
    # 标记无效深度
    depth_m[depth_mm == 0] = np.nan
    
    return depth_m

def save_depth(filepath, depth_m):
    """保存深度图"""
    depth_mm = (depth_m * 1000.0).astype(np.uint16)
    depth_mm[np.isnan(depth_m)] = 0
    cv2.imwrite(filepath, depth_mm)

2.4 IMU数据

格式:CSV

timestamp,accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z
1715875845.123456,-0.05,0.02,9.81,0.001,-0.002,0.000,25.3,10.2,-42.1
1715875845.133456,-0.04,0.03,9.80,0.002,-0.001,0.001,25.4,10.1,-42.0
...

字段说明

timestamp: Unix时间戳(秒,float64
accel_x/y/z: 加速度(m/s², float32
gyro_x/y/z: 角速度(rad/s, float32
mag_x/y/z: 磁场强度(μT, float32, 可选)

坐标系: 右手坐标系
  X: 
  Y: 
  Z: 

2.5 时间戳对齐文件

格式:timestamps.txt

# Timestamp alignment file
# Format: frame_id timestamp_unix sensor_type
# timestamp_unix: seconds since epoch (float64)

0000000 1715875845.123456 lidar
0000000 1715875845.125678 rgb
0000000 1715875845.126789 depth
0000001 1715875845.223456 lidar
0000001 1715875845.225678 rgb
0000001 1715875845.226789 depth
...

三、处理后数据格式

3.1 SLAM轨迹

格式:TUM格式(trajectory.txt

# TUM RGB-D SLAM trajectory format
# timestamp tx ty tz qx qy qz qw
# timestamp: Unix time (float64)
# tx ty tz: translation (meters)
# qx qy qz qw: rotation quaternion

1715875845.123456 0.000 0.000 0.000 0.000 0.000 0.000 1.000
1715875845.223456 0.050 0.001 0.002 0.001 0.002 0.003 0.999
1715875845.323456 0.102 0.003 0.004 0.002 0.004 0.006 0.998
...

Python读取示例

import numpy as np
from scipy.spatial.transform import Rotation

def load_trajectory(filepath):
    """加载TUM格式轨迹"""
    data = np.loadtxt(filepath)
    
    timestamps = data[:, 0]
    positions = data[:, 1:4]  # (N, 3)
    quaternions = data[:, 4:8]  # (N, 4) [qx, qy, qz, qw]
    
    # 转换为旋转矩阵
    rotations = Rotation.from_quat(quaternions).as_matrix()  # (N, 3, 3)
    
    # 构建4x4变换矩阵
    poses = np.zeros((len(data), 4, 4))
    poses[:, :3, :3] = rotations
    poses[:, :3, 3] = positions
    poses[:, 3, 3] = 1.0
    
    return timestamps, poses

def save_trajectory(filepath, timestamps, poses):
    """保存TUM格式轨迹"""
    N = len(timestamps)
    data = np.zeros((N, 8))
    
    data[:, 0] = timestamps
    data[:, 1:4] = poses[:, :3, 3]  # 位置
    
    # 旋转矩阵转四元数
    rotations = Rotation.from_matrix(poses[:, :3, :3])
    data[:, 4:8] = rotations.as_quat()  # [qx, qy, qz, qw]
    
    np.savetxt(filepath, data, fmt='%.6f')

3.2 COLMAP格式

cameras.txt

# Camera list with one line of data per camera:
#   CAMERA_ID, MODEL, WIDTH, HEIGHT, PARAMS[]
# Number of cameras: 1

1 PINHOLE 1920 1080 1066.778 1067.487 960.000 540.000

images.txt

# Image list with two lines of data per image:
#   IMAGE_ID, QW, QX, QY, QZ, TX, TY, TZ, CAMERA_ID, NAME
#   POINTS2D[] as (X, Y, POINT3D_ID)
# Number of images: 500

1 0.999 0.001 0.002 0.003 0.000 0.000 0.000 1 0000000.jpg
512.5 384.2 1234 678.9 456.1 5678 ...
2 0.998 0.002 0.004 0.006 0.050 0.001 0.002 1 0000001.jpg
510.3 382.7 1235 680.1 458.3 5679 ...
...

points3D.txt

# 3D point list with one line of data per point:
#   POINT3D_ID, X, Y, Z, R, G, B, ERROR, TRACK[] as (IMAGE_ID, POINT2D_IDX)
# Number of points: 123456

1 0.123 0.456 0.789 255 128 64 0.5 1 512 2 510 ...
2 0.234 0.567 0.890 200 150 100 0.3 1 678 3 680 ...
...

3.3 3D Gaussian Splatting格式

point_cloud.ply(初始点云)

ply
format binary_little_endian 1.0
element vertex 123456
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
property float nx
property float ny
property float nz
end_header
<binary data>

cameras.json

[
  {
    "id": 0,
    "img_name": "0000000",
    "width": 1920,
    "height": 1080,
    "position": [0.0, 0.0, 0.0],
    "rotation": [
      [1.0, 0.0, 0.0],
      [0.0, 1.0, 0.0],
      [0.0, 0.0, 1.0]
    ],
    "fy": 1067.487,
    "fx": 1066.778
  },
  ...
]

input.ply(优化后的高斯)

ply
format binary_little_endian 1.0
element vertex 500000
property float x
property float y
property float z
property float nx
property float ny
property float nz
property float f_dc_0
property float f_dc_1
property float f_dc_2
property float f_rest_0
...
property float f_rest_44
property float opacity
property float scale_0
property float scale_1
property float scale_2
property float rot_0
property float rot_1
property float rot_2
property float rot_3
end_header
<binary data>

字段说明

x, y, z: 高斯中心位置
nx, ny, nz: 法线(可选)
f_dc_*: 球谐函数DC分量(RGB
f_rest_*: 球谐函数高阶分量(45个)
opacity: 不透明度
scale_*: 缩放(3个轴)
rot_*: 旋转四元数(4个分量)

3.4 NeRF格式

transforms.json

{
  "camera_angle_x": 0.6911112070083618,
  "frames": [
    {
      "file_path": "./images/0000000",
      "rotation": 0.012566370614359171,
      "transform_matrix": [
        [0.999, -0.001, 0.002, 0.000],
        [0.001, 0.999, -0.003, 0.000],
        [-0.002, 0.003, 0.999, 0.000],
        [0.0, 0.0, 0.0, 1.0]
      ]
    },
    ...
  ]
}

3.5 网格模型(Mesh

OBJ格式

# Wavefront OBJ file
# Vertices: 123456
# Faces: 234567

mtllib scene.mtl

v 0.123 0.456 0.789
v 0.234 0.567 0.890
...

vn 0.577 0.577 0.577
vn 0.707 0.000 0.707
...

vt 0.500 0.500
vt 0.600 0.400
...

usemtl material_0
f 1/1/1 2/2/2 3/3/3
f 4/4/4 5/5/5 6/6/6
...

MTL格式(材质)

# Material file

newmtl material_0
Ka 0.2 0.2 0.2
Kd 0.8 0.8 0.8
Ks 0.5 0.5 0.5
Ns 96.078431
map_Kd textures/diffuse_0.png
map_Bump textures/normal_0.png
map_Ks textures/roughness_0.png

四、语义数据格式

4.1 2D检测结果(YOLO

yolo_results.json

{
  "version": "1.0",
  "model": "yolov9-world",
  "images": [
    {
      "image_id": "0000000",
      "image_path": "rgb/0000000.jpg",
      "width": 1920,
      "height": 1080,
      "detections": [
        {
          "detection_id": 0,
          "label": "bed",
          "confidence": 0.95,
          "bbox": [100, 200, 800, 600],
          "bbox_format": "xyxy",
          "mask_rle": "...",
          "clip_feature": [0.123, 0.456, ...]
        },
        {
          "detection_id": 1,
          "label": "desk",
          "confidence": 0.89,
          "bbox": [1000, 300, 1500, 900],
          "bbox_format": "xyxy"
        }
      ]
    }
  ]
}

4.2 3D实例

instances_3d.json

{
  "version": "1.0",
  "scene_id": "room_301",
  "coordinate_system": "right_hand_z_up",
  "unit": "meter",
  "instances": [
    {
      "instance_id": "bed_001",
      "label": "bed",
      "category": "furniture",
      "confidence": 0.95,
      "centroid": [1.5, 2.0, 0.5],
      "bbox_min": [0.5, 1.0, 0.0],
      "bbox_max": [2.5, 3.0, 1.0],
      "oriented_bbox": {
        "center": [1.5, 2.0, 0.5],
        "extent": [2.0, 2.0, 1.0],
        "rotation": [0.0, 0.0, 0.0, 1.0]
      },
      "volume": 4.0,
      "mesh_path": "mesh/bed_001.obj",
      "point_indices": [1234, 5678, ...],
      "semantic_feature": [0.123, 0.456, ...],
      "attributes": {
        "material": "fabric",
        "color": "white",
        "state": "made",
        "affordance": ["sittable", "lyable"]
      }
    }
  ]
}

4.3 场景图

scene_graph.json

{
  "version": "1.0",
  "scene_id": "room_301",
  "metadata": {
    "room_type": "hotel_room",
    "floor_area": 25.5,
    "ceiling_height": 2.8,
    "capture_date": "2026-05-16"
  },
  "nodes": [
    {
      "node_id": "bed_001",
      "type": "object",
      "label": "bed",
      "instance_ref": "bed_001",
      "properties": {
        "size": "queen",
        "material": "fabric",
        "color": "white"
      }
    },
    {
      "node_id": "nightstand_001",
      "type": "object",
      "label": "nightstand",
      "instance_ref": "nightstand_001"
    },
    {
      "node_id": "lamp_001",
      "type": "object",
      "label": "lamp",
      "instance_ref": "lamp_001"
    }
  ],
  "edges": [
    {
      "edge_id": 0,
      "source": "lamp_001",
      "target": "nightstand_001",
      "relation": "supported_by",
      "confidence": 0.98,
      "properties": {
        "contact_area": 0.05,
        "stability": "stable"
      }
    },
    {
      "edge_id": 1,
      "source": "nightstand_001",
      "target": "bed_001",
      "relation": "next_to",
      "confidence": 0.95,
      "properties": {
        "distance": 0.1,
        "side": "left"
      }
    }
  ]
}

五、物理数据格式

5.1 USD场景(Universal Scene Description

scene.usd(文本格式示例)

#usda 1.0
(
    defaultPrim = "World"
    metersPerUnit = 1
    upAxis = "Z"
)

def Xform "World"
{
    def Mesh "Bed"
    {
        float3[] extent = [(-1, -1, 0), (1, 1, 1)]
        int[] faceVertexCounts = [4, 4, 4, 4, 4, 4]
        int[] faceVertexIndices = [0, 1, 3, 2, ...]
        point3f[] points = [(0.5, 1.0, 0.0), ...]
        
        # 物理属性
        def PhysicsRigidBodyAPI
        {
            bool kinematicEnabled = true
        }
        
        def PhysicsMassAPI
        {
            float mass = 50.0
        }
        
        def PhysicsCollisionAPI
        {
        }
        
        def PhysicsMaterialAPI
        {
            float staticFriction = 0.5
            float dynamicFriction = 0.4
            float restitution = 0.1
        }
    }
    
    def Mesh "Wardrobe_Door"
    {
        # 铰接物体
        def PhysicsRevoluteJoint "Hinge"
        {
            rel body0 = </World/Wardrobe>
            rel body1 = </World/Wardrobe_Door>
            point3f localPos0 = (0, 0, 0)
            point3f localPos1 = (0.5, 0, 0)
            float3 axis = (0, 0, 1)
            float lowerLimit = 0.0
            float upperLimit = 120.0
        }
    }
}

5.2 铰接信息

articulation.json

{
  "version": "1.0",
  "scene_id": "room_301",
  "articulated_objects": [
    {
      "object_id": "wardrobe_door_001",
      "base_link": "wardrobe_001",
      "joint_type": "revolute",
      "joint_axis": [0, 0, 1],
      "joint_origin": [1.0, 2.0, 1.0],
      "joint_limits": {
        "lower": 0.0,
        "upper": 2.094,
        "effort": 10.0,
        "velocity": 1.0
      },
      "damping": 0.5,
      "friction": 0.1
    },
    {
      "object_id": "drawer_001",
      "base_link": "desk_001",
      "joint_type": "prismatic",
      "joint_axis": [1, 0, 0],
      "joint_origin": [1.5, 1.0, 0.7],
      "joint_limits": {
        "lower": 0.0,
        "upper": 0.4,
        "effort": 5.0,
        "velocity": 0.5
      }
    }
  ]
}

5.3 材质物理属性

material_props.json

{
  "version": "1.0",
  "materials": [
    {
      "material_id": "wood_oak",
      "density": 600.0,
      "static_friction": 0.5,
      "dynamic_friction": 0.4,
      "restitution": 0.3,
      "young_modulus": 11000000000.0,
      "poisson_ratio": 0.3,
      "damping": 0.1
    },
    {
      "material_id": "fabric_cotton",
      "density": 200.0,
      "static_friction": 0.7,
      "dynamic_