649 lines
19 KiB
Markdown
649 lines
19 KiB
Markdown
# 酒店场景室内建模与物理验证项目详细实施计划
|
||
|
||
## 项目概述
|
||
|
||
本项目旨在构建一套完整的酒店场景数字孪生系统,涵盖公共区域、客房和卫生间三大核心场景,实现从几何重建到物理交互验证的全流程闭环。项目将结合最新的3D重建技术(3DGS、NeRF)、SLAM建图、语义理解和物理世界模型(M-JEPA),为具身智能在真实复杂环境中的落地提供技术验证平台。
|
||
|
||
### 核心目标
|
||
|
||
1. **几何精度**:实现毫米级的三维重建精度
|
||
2. **语义丰富**:构建包含物体属性、空间关系的结构化场景图
|
||
3. **物理准确**:支持真实物理交互的数字孪生环境
|
||
4. **实时性能**:达到实时渲染与在线建图能力
|
||
5. **泛化能力**:验证技术方案在不同酒店场景的适用性
|
||
|
||
---
|
||
|
||
## 一、项目整体架构设计与技术选型
|
||
|
||
### 1.1 系统架构总览
|
||
|
||
```mermaid
|
||
graph TB
|
||
A[数据采集层] --> B[感知与建图层]
|
||
B --> C[语义理解层]
|
||
C --> D[物理交互层]
|
||
D --> E[应用验证层]
|
||
|
||
A1[LiDAR扫描] --> A
|
||
A2[RGB-D相机] --> A
|
||
A3[偏振相机] --> A
|
||
A4[IMU惯性] --> A
|
||
|
||
B1[SLAM定位] --> B
|
||
B2[3DGS重建] --> B
|
||
B3[点云融合] --> B
|
||
|
||
C1[YOLO检测] --> C
|
||
C2[SAM分割] --> C
|
||
C3[CLIP特征] --> C
|
||
C4[场景图构建] --> C
|
||
|
||
D1[M-JEPA模型] --> D
|
||
D2[物理仿真] --> D
|
||
D3[铰接感知] --> D
|
||
|
||
E1[机器人导航] --> E
|
||
E2[物体操作] --> E
|
||
E3[任务规划] --> E
|
||
```
|
||
|
||
### 1.2 分场景技术路线
|
||
|
||
| 场景类型 | 核心挑战 | 主要技术栈 | 预期输出 |
|
||
|---------|---------|-----------|---------|
|
||
| **公共区域**<br>大堂、走廊 | 大尺度、弱纹理<br>动态干扰多 | FAST-LIO2 / R3LIVE<br>YOLO动态滤除<br>Hierarchical 3DGS | 大规模点云地图<br>实时渲染模型 |
|
||
| **客房内部** | 空间紧凑、遮挡多<br>家具密集 | Gaussian-SLAM / Co-SLAM<br>SAM + CLIP语义<br>SceneCAD布局 | 高精度Mesh<br>3D场景图<br>CAD替身 |
|
||
| **卫生间** | 高反光、无纹理<br>镜面/玻璃多 | Ref-NeRF / Specular 3DGS<br>偏振相机<br>抗反射ToF | 抗反光重建<br>镜面几何分离 |
|
||
|
||
### 1.3 核心技术选型矩阵
|
||
|
||
#### SLAM与定位技术
|
||
|
||
| 技术方案 | 适用场景 | 优势 | 劣势 | 选用决策 |
|
||
|---------|---------|------|------|---------|
|
||
| **FAST-LIO2** | 公共区域 | 实时性强、抗退化 | 需LiDAR硬件 | ✅ 主选 |
|
||
| **R3LIVE** | 公共区域 | 视觉-LiDAR紧耦合 | 计算量大 | ✅ 备选 |
|
||
| **ORB-SLAM3** | 客房 | 纯视觉、成熟 | 弱纹理易失败 | ⚠️ 辅助 |
|
||
| **Gaussian-SLAM** | 客房 | 建图+渲染一体 | 内存占用高 | ✅ 主选 |
|
||
| **MonoGS** | 客房 | 单目实时 | 尺度漂移 | ✅ 备选 |
|
||
|
||
#### 三维重建技术
|
||
|
||
| 技术方案 | 渲染速度 | 几何精度 | 内存占用 | 可编辑性 | 选用决策 |
|
||
|---------|---------|---------|---------|---------|---------|
|
||
| **3D Gaussian Splatting** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ✅ 主选 |
|
||
| **Instant-NGP** | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ | ⚠️ 辅助 |
|
||
| **Mip-NeRF 360** | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⚠️ 高质量场景 |
|
||
| **NeuS / SuGaR** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ✅ Mesh提取 |
|
||
|
||
#### 语义理解技术
|
||
|
||
| 技术方案 | 检测速度 | 分割质量 | 开放词表 | 3D投影 | 选用决策 |
|
||
|---------|---------|---------|---------|--------|---------|
|
||
| **YOLOv9** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ❌ | ⭐⭐⭐⭐ | ✅ 实时检测 |
|
||
| **YOLO-World** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ✅ | ⭐⭐⭐⭐ | ✅ 开放词表 |
|
||
| **SAM** | ⭐⭐ | ⭐⭐⭐⭐⭐ | ❌ | ⭐⭐⭐ | ✅ 精细分割 |
|
||
| **CLIP** | ⭐⭐⭐ | N/A | ✅ | ⭐⭐⭐⭐⭐ | ✅ 特征提取 |
|
||
| **Mask3D** | ⭐⭐⭐ | ⭐⭐⭐⭐ | ❌ | ⭐⭐⭐⭐⭐ | ✅ 3D分割 |
|
||
|
||
### 1.4 软件栈与依赖
|
||
|
||
```yaml
|
||
核心框架:
|
||
- PyTorch: 2.1+
|
||
- CUDA: 12.1+
|
||
- ROS2: Humble
|
||
|
||
SLAM与重建:
|
||
- FAST-LIO2: C++实现
|
||
- Gaussian-Splatting: 官方实现 + 自定义扩展
|
||
- COLMAP: 位姿初始化
|
||
- Open3D: 点云处理
|
||
|
||
语义理解:
|
||
- Ultralytics: YOLOv9/YOLO-World
|
||
- Segment-Anything: SAM
|
||
- OpenCLIP: 特征提取
|
||
- Detectron2: Mask R-CNN备选
|
||
|
||
物理仿真:
|
||
- Isaac Sim: 主仿真器
|
||
- MuJoCo: 轻量级验证
|
||
- Genesis: 柔体/流体
|
||
|
||
数据管理:
|
||
- HDF5: 大规模数据存储
|
||
- MinIO: 对象存储
|
||
- PostgreSQL + PostGIS: 空间数据库
|
||
```
|
||
|
||
---
|
||
|
||
## 二、硬件设备与传感器配置方案
|
||
|
||
### 2.1 移动采集平台配置
|
||
|
||
#### 方案A:高精度科研平台(推荐)
|
||
|
||
```yaml
|
||
平台类型: 定制移动小车 / 手持稳定器
|
||
|
||
核心传感器:
|
||
LiDAR:
|
||
型号: Livox Mid-360 / Ouster OS1-64
|
||
扫描频率: 10Hz
|
||
测距范围: 0.05-70m
|
||
精度: ±2cm
|
||
|
||
RGB-D相机:
|
||
型号: Azure Kinect DK / RealSense L515
|
||
分辨率: 1920x1080 @ 30fps (RGB)
|
||
深度范围: 0.25-5.46m
|
||
深度精度: <1% @ 1m
|
||
|
||
高分辨率相机:
|
||
型号: Sony α7R IV / Canon EOS R5
|
||
分辨率: 61MP / 45MP
|
||
用途: 高质量纹理采集
|
||
|
||
偏振相机(卫生间专用):
|
||
型号: Lucid Phoenix 5.0 MP
|
||
偏振角度: 0°/45°/90°/135°
|
||
用途: 消除镜面反射
|
||
|
||
IMU:
|
||
型号: Xsens MTi-630
|
||
频率: 400Hz
|
||
精度: 0.2° (roll/pitch), 1° (yaw)
|
||
|
||
计算单元:
|
||
主机: NVIDIA Jetson AGX Orin 64GB
|
||
备用: Intel NUC 13 Pro (i7-1360P)
|
||
|
||
存储:
|
||
SSD: 2TB NVMe (现场缓存)
|
||
移动硬盘: 8TB (数据备份)
|
||
|
||
电源:
|
||
电池: 24V 20Ah 锂电池
|
||
续航: 4-6小时连续采集
|
||
|
||
预算: ¥15-20万
|
||
```
|
||
|
||
#### 方案B:轻量级快速部署(备选)
|
||
|
||
```yaml
|
||
平台类型: iPhone 15 Pro Max + LiDAR配件
|
||
|
||
核心传感器:
|
||
内置LiDAR: Apple LiDAR Scanner
|
||
主摄: 48MP (f/1.78)
|
||
超广角: 12MP (f/2.2)
|
||
长焦: 12MP (f/2.8, 5x)
|
||
|
||
配件:
|
||
- Structure Sensor Pro (外接高精度深度)
|
||
- DJI OM 6 稳定器
|
||
|
||
优势:
|
||
- 部署快速,成本低(¥2-3万)
|
||
- 便携性强
|
||
- 软件生态成熟(Polycam, 3D Scanner App)
|
||
|
||
劣势:
|
||
- 精度略低于专业设备
|
||
- 大场景扫描效率低
|
||
|
||
适用场景: 快速原型验证、小规模客房扫描
|
||
```
|
||
|
||
### 2.2 固定站点补充采集
|
||
|
||
```yaml
|
||
三脚架全景扫描:
|
||
设备: Matterport Pro3 / Leica BLK360
|
||
用途: 客房全景高精度补充
|
||
分辨率: 134MP 全景照片
|
||
扫描时间: 20秒/站点
|
||
|
||
无人机(公共区域高空视角):
|
||
型号: DJI Mavic 3 Enterprise
|
||
相机: 4/3 CMOS 20MP
|
||
用途: 大堂天花板、中庭俯视
|
||
```
|
||
|
||
### 2.3 传感器标定方案
|
||
|
||
```yaml
|
||
外参标定:
|
||
工具: Kalibr / CamOdoCal
|
||
标定板: AprilTag 6x6 阵列
|
||
流程:
|
||
1. LiDAR-Camera外参标定
|
||
2. 多相机时间同步校准
|
||
3. IMU-Camera外参标定
|
||
精度要求: 平移误差 < 5mm, 旋转误差 < 0.5°
|
||
|
||
内参标定:
|
||
相机: OpenCV棋盘格标定
|
||
LiDAR: 平面拟合验证
|
||
深度相机: 深度-RGB对齐验证
|
||
```
|
||
|
||
---
|
||
|
||
## 三、公共区域大规模SLAM建图模块
|
||
|
||
### 3.1 技术实现路线
|
||
|
||
#### 阶段1:多传感器融合SLAM
|
||
|
||
```python
|
||
# 伪代码框架
|
||
class PublicAreaSLAM:
|
||
def __init__(self):
|
||
self.lidar_odometry = FAST_LIO2() # 激光里程计
|
||
self.visual_frontend = ORB_SLAM3() # 视觉前端
|
||
self.imu_preintegration = IMUPreintegrator()
|
||
self.dynamic_filter = YOLODynamicFilter() # 动态物体滤除
|
||
|
||
def process_frame(self, lidar_scan, rgb_image, imu_data):
|
||
# 1. 动态物体检测与掩码
|
||
dynamic_mask = self.dynamic_filter.detect(rgb_image)
|
||
|
||
# 2. 滤除动态点云
|
||
static_lidar = self.filter_dynamic_points(
|
||
lidar_scan, dynamic_mask
|
||
)
|
||
|
||
# 3. LiDAR里程计估计
|
||
lidar_pose = self.lidar_odometry.track(static_lidar)
|
||
|
||
# 4. 视觉特征提取(静态区域)
|
||
visual_features = self.visual_frontend.extract_features(
|
||
rgb_image, mask=~dynamic_mask
|
||
)
|
||
|
||
# 5. 紧耦合优化
|
||
fused_pose = self.tightly_coupled_optimization(
|
||
lidar_pose, visual_features, imu_data
|
||
)
|
||
|
||
return fused_pose, static_lidar
|
||
```
|
||
|
||
**关键技术点**:
|
||
|
||
1. **动态滤除策略**
|
||
- 使用YOLO-World实时检测行人、行李车等动态物体
|
||
- 将2D检测框投影到3D点云,生成动态点掩码
|
||
- 采用时序一致性检查(连续3帧检测)避免误删
|
||
|
||
2. **长走廊退化处理**
|
||
- 引入IMU约束防止Z轴漂移
|
||
- 使用曼哈顿世界假设(Manhattan World)约束墙面平行
|
||
- 回环检测:基于Scan Context的LiDAR回环 + DBoW3视觉回环
|
||
|
||
3. **大规模地图管理**
|
||
- 采用分块(Submapping)策略,每20m×20m一个子图
|
||
- 子图间通过ICP + 特征匹配进行配准
|
||
- 全局位姿图优化(Pose Graph Optimization)
|
||
|
||
#### 阶段2:点云后处理与优化
|
||
|
||
```yaml
|
||
点云清洗:
|
||
- 统计滤波去除离群点(Statistical Outlier Removal)
|
||
- 体素下采样(Voxel Grid, 2cm分辨率)
|
||
- 地面分割与移除(RANSAC平面拟合)
|
||
|
||
点云配准:
|
||
- 粗配准: Fast Global Registration (FGR)
|
||
- 精配准: Colored ICP(结合RGB信息)
|
||
- 多视角融合: Poisson Surface Reconstruction
|
||
|
||
语义标注:
|
||
- 墙面/地面/天花板自动分割
|
||
- 柱子、门、窗户等结构元素提取
|
||
- 与CAD图纸对齐(如有)
|
||
```
|
||
|
||
#### 阶段3:Hierarchical 3DGS训练
|
||
|
||
```python
|
||
# 大规模3DGS训练流程
|
||
class HierarchicalGaussianSplatting:
|
||
def __init__(self, point_cloud, camera_poses):
|
||
self.build_hierarchy(point_cloud)
|
||
|
||
def build_hierarchy(self, pc):
|
||
# 1. 空间八叉树分割
|
||
self.octree = self.build_octree(pc, max_depth=5)
|
||
|
||
# 2. 每个节点独立训练3DGS
|
||
for node in self.octree.leaf_nodes:
|
||
node.gaussians = self.train_local_3dgs(
|
||
node.points,
|
||
node.cameras,
|
||
iterations=7000
|
||
)
|
||
|
||
# 3. 层级LOD构建
|
||
self.build_lod_pyramid()
|
||
|
||
def render(self, camera, target_fps=30):
|
||
# 根据相机距离动态选择LOD层级
|
||
visible_nodes = self.frustum_culling(camera)
|
||
lod_level = self.select_lod(camera.distance)
|
||
|
||
return self.hierarchical_render(
|
||
visible_nodes, lod_level
|
||
)
|
||
```
|
||
|
||
**训练参数**:
|
||
- 初始高斯数量:点云数量 × 1.5
|
||
- 迭代次数:30,000(全局) + 7,000(局部)
|
||
- 学习率:位置 0.00016,旋转 0.001,缩放 0.005
|
||
- 密度控制:每100次迭代进行高斯分裂/剪枝
|
||
|
||
### 3.2 实施步骤与时间规划
|
||
|
||
| 步骤 | 任务内容 | 关键交付物 | 依赖 |
|
||
|-----|---------|-----------|------|
|
||
| **3.1** | 环境勘察与路线规划 | 采集路线图、站点标记 | 硬件到位 |
|
||
| **3.2** | 传感器标定与测试 | 标定参数文件 | 硬件到位 |
|
||
| **3.3** | 数据采集(大堂) | 原始传感器数据包 | 3.1, 3.2 |
|
||
| **3.4** | 数据采集(走廊) | 原始传感器数据包 | 3.1, 3.2 |
|
||
| **3.5** | SLAM建图与位姿估计 | 轨迹文件、稀疏点云 | 3.3, 3.4 |
|
||
| **3.6** | 动态滤除与点云融合 | 静态点云地图 | 3.5 |
|
||
| **3.7** | Hierarchical 3DGS训练 | 实时渲染模型 | 3.6 |
|
||
| **3.8** | 质量评估与优化 | 评测报告、优化模型 | 3.7 |
|
||
|
||
**预计工期**:3-4周
|
||
|
||
### 3.3 质量评估指标
|
||
|
||
```yaml
|
||
几何精度:
|
||
- 点云配准误差: < 3cm (RMSE)
|
||
- 轨迹闭环误差: < 0.5% 总路径长度
|
||
- 墙面平整度: < 2cm 标准差
|
||
|
||
渲染质量:
|
||
- PSNR: > 28 dB
|
||
- SSIM: > 0.85
|
||
- LPIPS: < 0.15
|
||
|
||
性能指标:
|
||
- 渲染帧率: > 30 FPS @ 1080p (RTX 4090)
|
||
- 内存占用: < 16GB
|
||
- 加载时间: < 10秒
|
||
```
|
||
|
||
---
|
||
|
||
## 四、客房高保真稠密重建模块
|
||
|
||
### 4.1 数据采集策略
|
||
|
||
#### 4.1.1 多模态采集方案
|
||
|
||
```yaml
|
||
采集模式: 手持RGB-D + 固定站点全景
|
||
|
||
手持扫描路线:
|
||
1. 入口 → 环绕床铺 → 书桌区域
|
||
2. 衣柜内部(开门扫描)
|
||
3. 窗帘后方、床底等死角
|
||
4. 卫生间门口(不进入,单独处理)
|
||
|
||
固定站点(Matterport):
|
||
- 房间中心点 × 1
|
||
- 床头两侧 × 2
|
||
- 书桌前方 × 1
|
||
- 总计4-5个站点
|
||
|
||
采集密度:
|
||
- 手持扫描: 30cm间隔关键帧
|
||
- 总帧数: 300-500帧/房间
|
||
- 扫描时长: 15-20分钟/房间
|
||
```
|
||
|
||
#### 4.1.2 弱纹理区域增强
|
||
|
||
```python
|
||
class WeakTextureHandler:
|
||
def __init__(self):
|
||
self.depth_prior = DepthAnything() # 单目深度估计
|
||
self.lidar_depth = None # 物理深度真值
|
||
|
||
def enhance_pose_estimation(self, rgb_frames):
|
||
# 1. 提取稀疏特征点(ORB/SIFT)
|
||
sparse_features = self.extract_features(rgb_frames)
|
||
|
||
# 2. 对于特征稀疏区域,引入深度先验
|
||
for frame in rgb_frames:
|
||
if frame.feature_count < THRESHOLD:
|
||
# 使用深度大模型预测
|
||
depth_prior = self.depth_prior.predict(frame.rgb)
|
||
|
||
# 与LiDAR深度融合
|
||
if self.lidar_depth is not None:
|
||
depth_fused = self.fuse_depth(
|
||
depth_prior,
|
||
self.lidar_depth,
|
||
confidence_weight=0.7 # LiDAR权重更高
|
||
)
|
||
else:
|
||
depth_fused = depth_prior
|
||
|
||
# 生成虚拟特征点
|
||
frame.add_depth_constraints(depth_fused)
|
||
|
||
# 3. 联合优化相机位姿
|
||
optimized_poses = self.bundle_adjustment(
|
||
sparse_features, depth_constraints
|
||
)
|
||
|
||
return optimized_poses
|
||
```
|
||
|
||
### 4.2 高保真重建流程
|
||
|
||
#### 4.2.1 位姿估计与初始化
|
||
|
||
```bash
|
||
# COLMAP稀疏重建
|
||
colmap feature_extractor \
|
||
--database_path database.db \
|
||
--image_path images/ \
|
||
--ImageReader.camera_model PINHOLE \
|
||
--SiftExtraction.use_gpu 1
|
||
|
||
colmap exhaustive_matcher \
|
||
--database_path database.db \
|
||
--SiftMatching.use_gpu 1
|
||
|
||
colmap mapper \
|
||
--database_path database.db \
|
||
--image_path images/ \
|
||
--output_path sparse/
|
||
```
|
||
|
||
#### 4.2.2 3DGS训练与材质解耦
|
||
|
||
```python
|
||
class SpecularGaussianSplatting:
|
||
"""处理客房高反光材质的3DGS扩展"""
|
||
|
||
def __init__(self, config):
|
||
self.gaussians = GaussianModel(config)
|
||
self.enable_pbr = True # 启用物理渲染
|
||
|
||
def forward(self, viewpoint_camera):
|
||
# 标准3DGS渲染
|
||
color, depth, alpha = self.gaussians.render(viewpoint_camera)
|
||
|
||
if self.enable_pbr:
|
||
# 材质解耦:漫反射 + 镜面反射
|
||
diffuse, specular, roughness, metallic = \
|
||
self.decompose_material(color, viewpoint_camera)
|
||
|
||
# 环境光照贴图
|
||
env_map = self.estimate_environment_map()
|
||
|
||
# PBR着色
|
||
color_pbr = self.pbr_shading(
|
||
diffuse, specular, roughness, metallic,
|
||
env_map, viewpoint_camera
|
||
)
|
||
|
||
return color_pbr, depth, alpha
|
||
|
||
return color, depth, alpha
|
||
|
||
def decompose_material(self, color, camera):
|
||
"""分离漫反射与镜面反射"""
|
||
# 使用多视角一致性约束
|
||
# 漫反射:视角无关
|
||
# 镜面反射:视角相关(遵循反射定律)
|
||
|
||
# 简化实现:基于法线与视角夹角
|
||
normals = self.estimate_normals()
|
||
view_dir = camera.get_view_direction()
|
||
|
||
# Fresnel项估计镜面强度
|
||
fresnel = self.schlick_fresnel(normals, view_dir)
|
||
|
||
diffuse = color * (1 - fresnel)
|
||
specular = color * fresnel
|
||
|
||
# 粗糙度与金属度估计(可学习参数)
|
||
roughness = self.roughness_map
|
||
metallic = self.metallic_map
|
||
|
||
return diffuse, specular, roughness, metallic
|
||
```
|
||
|
||
**训练策略**:
|
||
- 第一阶段(0-7k iter):标准3DGS,学习基础几何
|
||
- 第二阶段(7k-15k iter):启用PBR,解耦材质
|
||
- 第三阶段(15k-30k iter):精细化,优化镜面反射
|
||
|
||
#### 4.2.3 Mesh提取与拓扑优化
|
||
|
||
```python
|
||
# 使用SuGaR提取高质量Mesh
|
||
from sugar import SuGaR
|
||
|
||
# 1. 从3DGS提取SDF
|
||
sdf_extractor = SuGaR(gaussians)
|
||
sdf_grid = sdf_extractor.extract_sdf(resolution=512)
|
||
|
||
# 2. Marching Cubes生成Mesh
|
||
from skimage.measure import marching_cubes
|
||
vertices, faces, normals, _ = marching_cubes(
|
||
sdf_grid, level=0.0, spacing=(0.01, 0.01, 0.01)
|
||
)
|
||
|
||
# 3. Mesh后处理
|
||
import trimesh
|
||
mesh = trimesh.Trimesh(vertices, faces, vertex_normals=normals)
|
||
|
||
# 移除小连通分量
|
||
mesh = mesh.split(only_watertight=False)[0]
|
||
|
||
# 平滑(保持边缘)
|
||
mesh = trimesh.smoothing.filter_laplacian(mesh, iterations=3)
|
||
|
||
# 简化(可选,用于实时仿真)
|
||
mesh = mesh.simplify_quadric_decimation(face_count=50000)
|
||
|
||
# 导出
|
||
mesh.export('room_mesh.obj')
|
||
```
|
||
|
||
### 4.3 语义理解与场景图构建
|
||
|
||
#### 4.3.1 2D语义提取
|
||
|
||
```python
|
||
class SemanticExtractor:
|
||
def __init__(self):
|
||
self.sam = SAM() # Segment Anything
|
||
self.clip = OpenCLIP() # 特征提取
|
||
self.yolo = YOLOWorld() # 开放词表检测
|
||
|
||
def extract_2d_semantics(self, rgb_image):
|
||
# 1. YOLO快速定位已知物体
|
||
detections = self.yolo.detect(
|
||
rgb_image,
|
||
text_prompts=[
|
||
"bed", "desk", "chair", "TV", "lamp",
|
||
"curtain", "wardrobe", "nightstand"
|
||
]
|
||
)
|
||
|
||
# 2. SAM精细分割
|
||
masks = []
|
||
for det in detections:
|
||
mask = self.sam.segment(
|
||
rgb_image,
|
||
box_prompt=det.bbox
|
||
)
|
||
masks.append(mask)
|
||
|
||
# 3. 提取CLIP特征
|
||
features = []
|
||
for mask in masks:
|
||
masked_region = rgb_image * mask
|
||
clip_feat = self.clip.encode_image(masked_region)
|
||
features.append(clip_feat)
|
||
|
||
return {
|
||
'masks': masks,
|
||
'features': features,
|
||
'labels': [det.label for det in detections],
|
||
'boxes': [det.bbox for det in detections]
|
||
}
|
||
```
|
||
|
||
#### 4.3.2 3D特征场融合
|
||
|
||
```python
|
||
class SemanticFeatureField:
|
||
"""将2D语义特征提升到3D空间"""
|
||
|
||
def __init__(self, gaussians, camera_poses):
|
||
self.gaussians = gaussians
|
||
self.cameras = camera_poses
|
||
self.feature_dim = 512 # CLIP特征维度
|
||
|
||
# 为每个高斯球添加语义特征
|
||
self.semantic_features = nn.Parameter(
|
||
torch.zeros(len(gaussians), self.feature_dim)
|
||
)
|
||
|
||
def project_2d_to_3d(self, semantic_2d_list):
|
||
"""多视角2D特征投影到3D高斯球"""
|
||
|
||
for view_idx, sem_2d in enumerate(semantic_2d_list):
|
||
camera = self.cameras[view_idx]
|
||
|
||
# 渲染深度图,获取每个像素对应的高斯球ID
|
||
gaussian_ids = self.render_gaussian_id_map(camera)
|
||
|
||
# 将2D特征分配给对应的3D高斯球
|
||
for mask, feature in zip(sem_2d['masks'], sem_2d['features']):
|
||
# 获取mask覆盖的高斯球
|
||
affected_gaussians = gaussian_ids[mask > 0.5]
|
||
|
||
# 累积特征(后续取平均)
|
||
for gid in affected_gaussians.unique():
|
||
self.semantic_features[gid] += feature
|
||
self.feature_count[gid] += 1
|
||
|
||
# 归一化(多视角平均) |