Files
2026_DesignAI/officefile/05-3d-spatial/05-3d-spatial.md
T
pengxiao 219232de74 refactor: 重组项目目录结构
以讲义内容为骨架迁移到标准目录格式:
- officefile/ 主内容(12章 + 附录 + CC4SI补充)
- dofile/ 代码示例(11个Python脚本)
- data/ 图片资源
- output/ 生成输出(忽略)
- Archive/ 归档旧目录(忽略)
- .claude/skills/ 保留markdown-to-docx工具链
- .pandoc/ 保留CSL和本地化配置

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 14:00:56 +08:00

1422 lines
45 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第5章:三维数据——空间与3D
## 篇章导读
三维数据是AI与物理世界之间最直接的桥梁。从建筑到城市规划,从景观到工业设计,空间理解始终是设计实践的核心能力。一架无人机飞过城市上空,激光雷达 (LiDAR) 每秒发射数十万束激光,返回的每一个点都在描述一个真实的空间坐标——这些点汇聚成点云,构成数字世界的三维基础。一个设计师用手机扫描房间,几秒钟后便得到完整的三维模型;一位规划师输入"现代化办公椅"的文本描述,AI便能生成一个可编辑的3D模型。
这些场景不再是科幻。从传统的多视图立体匹配 (MVS) 到神经辐射场 (NeRF),从三维高斯溅射 (3D Gaussian Splatting) 到大规模空间智能模型,三维AI正在经历从小模型到大模型、从感知到推理的范式跃迁。本章将带你走进三维数据的世界,理解AI如何"看见"和"重建"空间,并探索空间智能在设计领域的广阔应用。
---
# 5.1 三维数据表示
## 学习目标
- 理解四种主要3D数据表示形式的特点与适用场景
- 掌握点云、网格、体素、深度图的区别与联系
- 了解Open3D等工具的基本使用方法
### 为什么需要多种3D表示
现实世界是三维的,但计算机需要用特定的数据结构来存储和处理3D信息。不同的表示方式在精度、内存效率和处理难度上各有权衡,选择合适的表示方式是3D AI的第一步。
```
物理世界
↓ 采集/建模
三维数据 ──→ 点云 (Point Cloud)
──→ 网格 (Mesh)
──→ 体素 (Voxel)
──→ 深度图 (Depth Map)
```
### 点云 (Point Cloud)
**定义**:一组三维坐标点的集合,每个点包含 (x, y, z) 坐标,可选附加颜色 (r, g, b)、法向量等属性。
```
点云示例:
● ●
● ●
● ● ●
● ●
● ●
每个点:P = (x, y, z) 或 (x, y, z, r, g, b)
```
**特点**
- 最接近原始传感器数据的表示形式
- 不规则、无序、无拓扑关系
- 点的数量可变(置换不变性问题)
- 适合大规模场景的快速采集
**常见来源**
- 激光雷达 (LiDAR):自动驾驶、城市扫描
- 深度相机 (RGB-D Camera):室内扫描、物体识别
- 摄影测量 (Photogrammetry):无人机航拍重建
### 网格 (Mesh)
**定义**:由顶点 (Vertices)、边 (Edges) 和面 (Faces) 组成的多面体表示,是最常见的3D模型格式。
```
网格结构:
v₁ ──── v₂
| |
| f₁ |
| |
v₃ ──── v₄
顶点:v₁, v₂, v₃, v₄ (各含 x, y, z 坐标)
面: f₁ = (v₁, v₂, v₃), f₂ = (v₂, v₃, v₄) 等
```
**特点**
- 具有拓扑关系,能表示物体表面
- 渲染效率高,是游戏、动画的标准格式
- 文件格式:OBJ, STL, PLY, FBX 等
- 适合设计建模和可视化
### 体素 (Voxel)
**定义**:三维空间中的规则网格单元,是二维像素 (Pixel) 在三维空间的推广——"三维像素"。
```
体素网格:
┌───┬───┬───┐
│ 1 │ 0 │ 1 │ 1 = 占据
├───┼───┼───┤ 0 = 空闲
│ 0 │ 1 │ 0 │
├───┼───┼───┤
│ 1 │ 1 │ 0 │
└───┴───┴───┘
类似"我的世界"(Minecraft)的方块表示
```
**特点**
- 规则网格结构,可直接使用3D卷积
- 内存消耗与分辨率的立方成正比
- 分辨率有限时存在"方块效应"
- 适合3D卷积神经网络处理
### 深度图 (Depth Map)
**定义**:二维图像,每个像素存储的是该位置到相机的距离(深度值),也称2.5D表示。
```
深度图:
┌─────┬─────┬─────┐
│ 2.1 │ 2.3 │ 8.5 │ 数值 = 到相机的距离
├─────┼─────┼─────┤ (单位:米)
│ 2.0 │ 2.2 │ 9.1 │
├─────┼─────┼─────┤
│ 2.2 │ 2.1 │ 8.8 │
└─────┴─────┴─────┘
近处物体:深度值小 (2.0)
远处背景:深度值大 (9.1)
```
**特点**
- 本质是二维数组,处理效率高
- 只包含单视角的深度信息(不完全的3D)
- 可直接与RGB图像对齐
- 常见于深度相机(Kinect, RealSense)输出
### 四种表示方式对比
| 特性 | 点云 (Point Cloud) | 网格 (Mesh) | 体素 (Voxel) | 深度图 (Depth Map) |
|------|--------------------|--------------|---------------|---------------------|
| 数据结构 | 无序点集 | 顶点 + 面 | 规则3D网格 | 2D数组 |
| 内存效率 | 较高 | 高 | 低(立方增长) | 高 |
| 分辨率 | 灵活(点密度) | 可调(面数) | 受网格限制 | 受图像分辨率限制 |
| 拓扑信息 | 无 | 有 | 隐含 | 无 |
| 深度学习适配 | 需特殊处理 | 需转换 | 直接3D卷积 | 直接2D卷积 |
| 常见来源 | LiDAR, RGB-D | 建模软件 | 体素化转换 | 深度相机 |
| 典型应用 | 场景扫描 | 设计建模 | 3D语义分割 | 室内导航 |
### 代码实践:点云加载与可视化
以下示例使用 Open3D 库加载并可视化一个点云文件:
```python
import open3d as o3d
import numpy as np
# 创建一个示例点云(模拟简单的建筑体量)
pcd = o3d.geometry.PointCloud()
# 生成一个"盒子"形状的点云
points = []
# 底面
for x in np.linspace(0, 10, 50):
for y in np.linspace(0, 8, 40):
points.append([x, y, 0])
points.append([x, y, 5]) # 顶面
# 侧面
for x in np.linspace(0, 10, 50):
for z in np.linspace(0, 5, 25):
points.append([x, 0, z])
points.append([x, 8, z])
for y in np.linspace(0, 8, 40):
for z in np.linspace(0, 5, 25):
points.append([0, y, z])
points.append([10, y, z])
pcd.points = o3d.utility.Vector3dVector(np.array(points))
# 统计点云信息
print(f"点云包含 {len(pcd.points)} 个点")
print(f"边界框: {pcd.get_min_bound()} ~ {pcd.get_max_bound()}")
# 可视化
o3d.visualization.draw_geometries(
[pcd],
window_name="建筑体量点云",
width=800, height=600,
point_show_normal=False
)
```
加载真实点云文件(如 PLY 格式)只需一行:
```python
pcd = o3d.io.read_point_cloud("building_scan.ply")
o3d.visualization.draw_geometries([pcd])
```
### 思考与练习
1. 为什么点云是无序的?这对深度学习模型设计有什么影响?
2. 如果要表示一个室内场景,哪种3D表示方式最合适?为什么?
3. 体素的内存消耗与分辨率的关系是什么?分辨率为256^3时有多少个体素?
### 关键术语
| 中文 | 英文 | 说明 |
|------|------|------|
| 点云 | Point Cloud | 三维坐标点的集合 |
| 网格 | Mesh | 顶点、边、面组成的多面体表示 |
| 体素 | Voxel | 三维空间中的规则网格单元 |
| 深度图 | Depth Map | 存储距离信息的二维图像 |
| 激光雷达 | LiDAR | 激光测距传感器 |
| 法向量 | Normal Vector | 垂直于表面的方向向量 |
### 延伸阅读
- [Open3D 官方文档](http://www.open3d.org/docs/)
- [Point Cloud Library (PCL)](https://pointclouds.org/)
---
# 5.2 三维理解
## 学习目标
- 理解PointNet的核心创新:直接处理点云的置换不变性
- 了解三维目标检测与分割的基本方法
- 掌握3D理解在设计领域的典型应用场景
### 小模型时代的3D理解
在Transformer等大模型出现之前,3D深度学习主要依赖专门设计的小型网络架构。核心挑战在于:三维数据不像图像那样具有规则的网格结构,无法直接使用标准卷积操作。
```
3D理解的三个核心任务:
输入: 三维数据 (点云/网格/体素/深度图)
├── 3D分类: "这是什么?" → 类别标签
├── 3D检测: "物体在哪?" → 3D边界框 + 类别
└── 3D分割: "每个部分是什么?" → 逐点/逐体素标签
```
### PointNet (2017):直接处理点云
#### 核心问题
点云是无序集合。同样的点集,无论以什么顺序输入,输出应该相同——这就是**置换不变性** (Permutation Invariance)。
```
同一个物体的点云,点的排列顺序不同:
表示1: {P₁, P₂, P₃, ..., Pₙ}
表示2: {P₃, P₁, Pₙ, ..., P₂} ← 顺序不同
表示3: {Pₙ, Pₙ₋₁, ..., P₁} ← 完全倒序
期望:f(表示1) = f(表示2) = f(表示3)
```
#### PointNet的解决方案
```
输入点云: N × 3 (N个点,每个3个坐标)
逐点MLP: 3 → 64 → 128 → 1024 (对每个点独立处理)
对称函数: Max Pooling (取每个特征维度的最大值)
全局特征: 1 × 1024
全连接层 → 分类/分割输出
关键: Max Pooling 天然满足置换不变性
max(a, b, c) = max(c, a, b) = max(b, c, a)
```
#### PointNet架构简图
```
输入点云 T-Net MLP Max Pooling 全连接
(N×3) → (空间变换换) → (64→128→1024) → (1×1024) → 输出
↑ ↑
对齐输入 全局特征向量
```
**T-Net**:学习一个空间变换矩阵,将输入点云对齐到规范姿态(类似空间归一化)。
#### 代码示例:理解PointNet的核心思想
```python
import torch
import torch.nn as nn
class SimplePointNet(nn.Module):
"""简化版PointNet,展示核心思想"""
def __init__(self, num_classes=10):
super().__init__()
# 逐点MLP:对每个点独立提取特征
self.mlp = nn.Sequential(
nn.Linear(3, 64),
nn.ReLU(),
nn.Linear(64, 128),
nn.ReLU(),
nn.Linear(128, 1024)
)
# 分类头
self.classifier = nn.Sequential(
nn.Linear(1024, 512),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(512, num_classes)
)
def forward(self, x):
# x: (batch_size, num_points, 3)
x = self.mlp(x) # (B, N, 1024)
x = torch.max(x, dim=1)[0] # (B, 1024) ← 对称函数!
x = self.classifier(x) # (B, num_classes)
return x
# 测试置换不变性
model = SimplePointNet(num_classes=5)
points = torch.randn(1, 100, 3) # 1个样本,100个点
# 原始顺序
out1 = model(points)
# 随机打乱顺序
perm = torch.randperm(100)
out2 = model(points[:, perm, :])
print(f"输出差异: {torch.max(torch.abs(out1 - out2)).item():.6f}")
# 输出差异应接近0 —— 置换不变性!
```
### PointNet++:层次化点集学习
PointNet将所有点直接映射为全局特征,缺乏捕捉局部结构的能力。PointNet++引入了层次化 (Hierarchical) 结构:
```
PointNet: 所有点 ──→ 全局特征 (单层,无局部结构)
PointNet++: 点集 → 局部区域1 → 局部区域2 → ... → 全局特征
↑ 每层都是一个小PointNet
↑ 逐步扩大感受野
```
```
层次化处理流程:
输入: N个点
↓ 采样 + 分组 (Ball Query)
N个局部区域 (每个含K个点)
↓ 对每个区域用 PointNet
N'个新的特征点
↓ 采样 + 分组
更少的局部区域
↓ 对每个区域用 PointNet
全局特征
```
**核心改进**
- **最远点采样 (Farthest Point Sampling)**:均匀选取中心点
- **球查询 (Ball Query)**:查找半径范围内的邻域点
- **多尺度分组 (MSG)**:不同半径捕捉不同尺度的局部特征
### 基于体素的3D CNN
另一种思路是将不规则3D数据转换为规则网格,然后使用3D卷积:
```
点云/网格
↓ 体素化 (Voxelization)
规则体素网格 (如 32×32×32)
↓ 3D卷积
3D特征图
↓ 分类/检测/分割
2D卷积核: H × W (如 3×3)
3D卷积核: D × H × W (如 3×3×3)
```
**优势**:可直接利用成熟的CNN框架
**劣势**:内存消耗大(分辨率立方增长)、量化损失
### 三维目标检测与分割
#### 3D目标检测
```
输入: 3D场景 (点云/体素)
3D检测器
输出: 3D边界框 [(x, y, z, l, w, h, θ, class), ...]
位置 长宽高 朝向 类别
```
代表性方法:
| 方法 | 类型 | 特点 |
|------|------|------|
| VoteNet (2019) | 点云投票 | 从点云直接预测3D框 |
| PointPillars (2019) | 点云→伪图像 | 高效的激光雷达检测 |
| VoxelNet (2018) | 体素化 | 端到端3D检测 |
| CenterPoint (2021) | 中心点检测 | 以中心 heatmap 方式检测 |
#### 3D语义分割
```
室内场景点云
↓ 逐点分类
[墙壁, 墙壁, 地板, 地板, 椅子, 椅子, 桌子, ...]
每个点获得语义标签
```
### 设计应用
#### 建筑足迹提取
```
无人机激光扫描
3D点云数据
↓ PointNet++ / 语义分割
地面点 | 建筑点 | 植被点
建筑足迹向量 (可导入GIS/CAD)
```
#### 地形分类
```
LiDAR地形扫描
↓ 3D语义分割
分类结果: [裸地, 草地, 灌木, 林地, 水体, 道路]
用于景观规划、生态评估
```
#### 室内场景理解
```
深度相机扫描
↓ 3D实例分割
[墙1, 墙2, 地板, 天花板, 沙发, 桌子, 椅子1, 椅子2]
自动生成室内平面图和家具布局
```
### 思考与练习
1. PointNet的Max Pooling为什么能满足置换不变性?除了Max Pooling,还有哪些对称函数?
2. 体素表示为什么内存消耗大?如果场景中有大量空白区域,如何优化?
3. 设计一个用PointNet对建筑风格进行分类的方案,需要哪些数据和步骤?
### 关键术语
| 中文 | 英文 | 说明 |
|------|------|------|
| 置换不变性 | Permutation Invariance | 输入顺序不影响输出 |
| 对称函数 | Symmetric Function | 对输入顺序不敏感的函数 |
| 最远点采样 | Farthest Point Sampling | 均匀选取代表点 |
| 球查询 | Ball Query | 查找半径内的邻域点 |
| 3D边界框 | 3D Bounding Box | 三维空间中的矩形框 |
| 体素化 | Voxelization | 将不规则数据转为规则体素 |
### 延伸阅读
- [PointNet: Deep Learning on Point Sets (Qi et al., 2017)](https://arxiv.org/abs/1612.00593)
- [PointNet++: Deep Hierarchical Feature Learning (Qi et al., 2017)](https://arxiv.org/abs/1706.02413)
---
# 5.3 三维重建与生成
## 学习目标
- 理解传统3D重建方法(SfM、MVS)的基本原理
- 掌握NeRF和3D Gaussian Splatting的核心思想
- 了解Text-to-3D和Image-to-3D生成模型的发展
### 从传统方法到神经渲染
三维重建是从2D图像或传感器数据中恢复3D场景的过程。从传统几何方法到深度学习驱动的方法,这一领域经历了革命性的变化。
```
3D重建方法演进:
传统几何方法 (2000s)
SfM → MVS → 稠密点云
深度学习增强 (2015+)
学习型MVS → 更鲁棒的重建
神经渲染 (2020)
NeRF: 神经网络隐式表示场景
显式表示复兴 (2023)
3D Gaussian Splatting: 高效实时渲染
3D大模型生成 (2023+)
Text-to-3D / Image-to-3D
```
### 传统方法
#### Structure from Motion (SfM,运动恢复结构)
**核心思想**:从一系列不同角度拍摄的2D照片中,同时恢复相机的位置 (运动) 和场景的3D结构。
```
SfM流程:
多张照片 (不同角度)
↓ 特征提取与匹配
特征对应关系
↓ 几何约束求解
相机位姿 (位置+朝向)
↓ 三角测量
稀疏3D点云
```
```
相机1 场景点P 相机2
○ ──────── x ←───────→ x ────────── ○
光线1 光线2
╲ ╱
╲ ╱
╲ 交点= ╱
╲ P的3D
位置
```
**关键步骤**
1. **特征检测**SIFT/SUPERPOINT等算法检测每张图片的关键特征
2. **特征匹配**:在不同图片之间找到相同的特征点
3. **运动估计**:根据匹配关系计算相机运动
4. **三角测量**:利用两个视角的射线交汇得到3D坐标
#### Multi-View Stereo (MVS,多视图立体匹配)
SfM只产生稀疏点云,MVS则在此基础上生成稠密重建:
```
SfM稀疏点云
MVS稠密匹配
稠密点云 / 深度图
表面重建 (Poisson, Delaunay)
完整3D网格模型
```
**局限性**
- 对纹理缺乏区域(白墙、玻璃)重建效果差
- 计算耗时较长
- 难以处理反光、透明材质
### NeRF (Neural Radiance Fields,神经辐射场)
2020年,加州大学伯克利分校的研究团队提出了NeRF,彻底改变了3D重建的范式。
#### 核心思想
不再显式存储3D模型(点云/网格),而是用一个神经网络来"记住"整个三维场景:
```
传统: 场景 → 存储为点云/网格/体素
NeRF: 场景 → 训练一个神经网络
网络输入: (x, y, z, θ, φ)
3D坐标 观察方向
网络输出: (r, g, b, σ)
颜色 密度
```
```
┌──────────────────┐
(x,y,z,θ,φ) ────→ │ MLP │ ────→ (r, g, b)
空间位置+视角 │ (8-12层, 256宽) │
│ │ ────→ σ (密度)
└──────────────────┘
σ 控制该点是否"有物体"
σ ≈ 0 → 空气(光线直接穿过)
σ ≈ 大 → 实体(光线被吸收/着色)
```
#### 体渲染 (Volume Rendering)
NeRF通过体渲染将3D神经场合成为2D图像:
```
对于图像上的每个像素:
从相机发射一条光线穿过场景
沿光线采样多个3D点
对每个点查询NeRF网络得到(颜色, 密度)
沿光线积分 → 像素颜色
C(r) = ∫ T(t) · σ(t) · c(t) dt
其中 T(t) = exp(-∫ σ(s) ds) 是透射率
```
直观理解:
```
相机 ──光线──→ ●密度高(墙) ──→ ●密度低(窗) ──→ ●密度高(树)
颜色=灰色 颜色=透明 颜色=绿色
↓ ↓ ↓
最终权重=高 权重=低 权重=中
最终像素颜色 = 加权混合
```
#### 训练过程
```
输入: 多张不同角度的照片 + 相机参数
对每张照片的每个像素:
1. 发射光线
2. 采样3D点,查询MLP
3. 体渲染得到预测颜色
计算损失: L = ||预测颜色 - 真实像素颜色||²
反向传播,更新MLP权重
重复数万次 → MLP"记住"了整个场景
```
#### NeRF的优势与局限
| 优势 | 局限 |
|------|------|
| 重建质量极高 | 训练慢(数小时/场景) |
| 能处理复杂光照 | 渲染慢(逐光线查询MLP) |
| 连续表示,无分辨率限制 | 难以编辑/修改 |
| 不需要网格/纹理等显式表示 | 泛化能力有限(每场景训练) |
### 3D Gaussian Splatting (三维高斯溅射, 2023)
NeRF的隐式表示虽然质量高,但速度慢、难以编辑。3D Gaussian Splatting (3DGS) 用显式的高斯椭球体取代了隐式神经网络,实现了实时渲染。
#### 核心思想
场景由大量3D高斯椭球体组成,每个高斯体具有:
```
一个3D高斯体的属性:
- 位置 μ = (x, y, z) ← 在哪
- 协方差 Σ (旋转+缩放) ← 形状
- 不透明度 α ← 透明度
- 球谐系数 SH ← 颜色(依赖视角)
数学表示:
G(x) = exp(-½(x-μ)ᵀ Σ⁻¹ (x-μ))
```
```
场景表示:
● = 高斯体1 (椭圆,浅蓝,半透明)
● = 高斯体2 (圆形,深蓝,不透明)
● = 高斯体3 (扁平,白色,透明)
● = ...
成千上万个高斯体叠加 → 完整场景
```
#### Splatting(溅射)过程
```
3D高斯体 → 投影到2D图像平面 → 排序 → 混合 → 最终图像
名称由来: 像把"颜料"溅射 (Splat) 到画布上
```
```
3D空间 2D图像
● ● ● ┌─────────┐
● ● ● ● ● 投影→ │ 渲染结果 │
● ● ● │ (实时) │
● ● └─────────┘
3D高斯体 ──→ 2D椭圆 ──→ 按深度排序 ──→ Alpha混合
```
#### 3DGS vs NeRF
| 特性 | NeRF | 3D Gaussian Splatting |
|------|------|------------------------|
| 场景表示 | 隐式 (MLP权重) | 显式 (高斯体集合) |
| 训练时间 | 数小时 | 数分钟到数十分钟 |
| 渲染速度 | 慢(逐点查询) | 实时(>100 FPS |
| 渲染质量 | 高 | 高(相当或更好) |
| 可编辑性 | 困难 | 可以操作高斯体 |
| 存储 | 小(网络权重) | 较大(百万高斯体) |
### 3D生成模型
从2023年开始,AI不仅能"重建"已有场景,还能从零"生成"新的3D内容。
#### Text-to-3D (文本生成3D)
```
文本描述 → 3D生成模型 → 3D模型
示例:
"a modern office chair with armrests"
→ 可编辑的3D办公椅模型
"a traditional Chinese pavilion"
→ 中国古亭的3D模型
```
#### Image-to-3D (图像生成3D)
```
单张照片 → 3D生成模型 → 3D模型
示例:
一张建筑立面照片 → 完整的3D建筑模型
一张产品照片 → 360°可旋转的3D模型
```
#### 代表性方法
| 模型 | 年份 | 输入 | 方法 | 特点 |
|------|------|------|------|------|
| DreamFusion | 2022 | 文本 | SDS + NeRF | 首个高质量Text-to-3D |
| Point-E | 2022 | 文本 | 扩散模型→点云 | 速度快,质量一般 |
| Shap-E | 2023 | 文本/图像 | 扩散模型→隐式函数 | 支持3D和纹理 |
| LRM | 2023 | 图像 | Transformer | 大规模重建模型 |
| TripoSR | 2024 | 图像 | Transformer+NeRF | 开源,快速单图重建 |
| CLAY | 2024 | 文本 | 大型3D原生模型 | 设计级3D生成 |
| Trellis | 2024 | 文本/图像 | 结构化隐式+高斯 | 高质量,可编辑 |
#### DreamFusion的SDS原理 (Score Distillation Sampling)
DreamFusion的核心创新在于:利用预训练的2D扩散模型来指导3D生成。
```
思路:
2D扩散模型懂得"什么图像是合理的"
→ 让它来"指导"3D模型的渲染结果
随机初始化的NeRF
↓ 渲染为2D图像
2D扩散模型评估并给出梯度
↓ 更新NeRF参数
反复迭代
NeRF渲染出的图像越来越好
→ NeRF本身就是一个好的3D模型
```
### 代码示例:简化版NeRF概念实现
以下代码展示NeRF的核心组件——一个将3D坐标和观察方向映射为颜色和密度的MLP:
```python
import torch
import torch.nn as nn
class SimpleNeRF(nn.Module):
"""简化版NeRF,展示核心映射思想"""
def __init__(self, pos_dim=3, dir_dim=3, hidden=64):
super().__init__()
# 位置编码 (Positional Encoding) 提升高频细节
self.pos_encode_freq = 6 # 编码频率数
# 编码后的维度: 3 × 2 × 6 = 36 (sin+cos, 6个频率)
encoded_pos_dim = pos_dim * 2 * self.pos_encode_freq
# 主干网络: 处理空间位置
self.backbone = nn.Sequential(
nn.Linear(encoded_pos_dim, hidden),
nn.ReLU(),
nn.Linear(hidden, hidden),
nn.ReLU(),
nn.Linear(hidden, hidden),
nn.ReLU(),
)
# 密度分支: 从位置预测密度
self.density_head = nn.Linear(hidden, 1)
# 颜色分支: 从位置+方向预测颜色
self.color_head = nn.Sequential(
nn.Linear(hidden + dir_dim, hidden // 2),
nn.ReLU(),
nn.Linear(hidden // 2, 3),
nn.Sigmoid() # 颜色值在[0,1]
)
def positional_encoding(self, x):
"""位置编码: 让MLP能学习高频细节"""
encoded = []
for freq in range(self.pos_encode_freq):
for fn in [torch.sin, torch.cos]:
encoded.append(fn(2**freq * x))
return torch.cat(encoded, dim=-1)
def forward(self, positions, directions):
"""
positions: (B, 3) - 3D空间坐标
directions: (B, 3) - 观察方向
"""
# 位置编码
encoded_pos = self.positional_encoding(positions)
# 提取特征
features = self.backbone(encoded_pos)
# 预测密度
density = self.density_head(features) # (B, 1)
# 预测颜色 (依赖位置和观察方向)
color = self.color_head(
torch.cat([features, directions], dim=-1)
) # (B, 3)
return color, density
# 演示: 查询一个空间点的颜色和密度
model = SimpleNeRF()
pos = torch.randn(100, 3) # 100个空间点
dir = torch.randn(100, 3) # 100个观察方向
dir = dir / dir.norm(dim=-1, keepdim=True) # 归一化方向
color, density = model(pos, dir)
print(f"颜色范围: [{color.min():.3f}, {color.max():.3f}]")
print(f"密度范围: [{density.min():.3f}, {density.max():.3f}]")
print(f"颜色形状: {color.shape}, 密度形状: {density.shape}")
```
### 思考与练习
1. NeRF中位置编码 (Positional Encoding) 的作用是什么?没有它会发生什么?
2. 3D Gaussian Splatting 为什么比NeRF渲染速度快?从数据结构的角度分析。
3. 如果要为一个建筑外观设计项目选择3D重建方案,你会选择NeRF还是3DGS?为什么?
### 关键术语
| 中文 | 英文 | 说明 |
|------|------|------|
| 神经辐射场 | NeRF | 用MLP隐式表示3D场景 |
| 体渲染 | Volume Rendering | 沿光线积分合成图像 |
| 三维高斯溅射 | 3D Gaussian Splatting | 用高斯椭球体显式表示场景 |
| 运动恢复结构 | Structure from Motion (SfM) | 从照片恢复3D结构和相机位姿 |
| 多视图立体匹配 | Multi-View Stereo (MVS) | 从多视角生成稠密3D重建 |
| 位置编码 | Positional Encoding | 用三角函数提升高频细节表达 |
### 延伸阅读
- [NeRF: Representing Scenes as Neural Radiance Fields (Mildenhall et al., 2020)](https://arxiv.org/abs/2003.08934)
- [3D Gaussian Splatting for Real-Time Radiance Field Rendering (Kerbl et al., 2023)](https://arxiv.org/abs/2308.04079)
- [DreamFusion: Text-to-3D using 2D Diffusion (Poole et al., 2022)](https://arxiv.org/abs/2209.14988)
---
# 5.4 空间智能
## 学习目标
- 理解空间智能的概念及其对设计领域的意义
- 了解多模态空间推理和场景理解的前沿方向
- 掌握数字孪生的四个演进层次
- 认识GIS+AI的融合趋势
### 从3D感知到空间推理
前两节我们学习了AI如何"感知"和"重建"三维世界。空间智能 (Spatial Intelligence) 则更进一步——不仅要感知空间,还要理解和推理空间中的关系、规律与语义。
```
3D能力层次:
感知层: 识别物体和几何形状
理解层: 理解空间语义(这是什么空间?功能是什么?)
推理层: 空间关系推理(A在B的左边,C挡住了D的视线)
规划层: 基于空间理解进行决策和设计
```
**为什么空间智能对设计至关重要?**
设计本质上是空间思维的活动——建筑师需要理解空间的比例与流线,景观设计师需要分析地形与视廊,城市规划师需要把握城市形态与功能关系。AI如果能够理解空间,就能成为设计过程中的真正协作伙伴。
### 多模态空间推理
#### 概念
将视觉信息、语言描述和三维空间理解结合起来,进行空间相关的推理和问答。
```
输入: 一张室内照片 + 问题 "沙发后面是什么?"
↓ 多模态空间推理
输出: "沙发后面是一面挂画的白墙"
```
```
多模态空间推理框架:
视觉模态 ──→ 视觉编码器 ──┐
├──→ 空间推理模块 ──→ 回答/决策
语言模态 ──→ 语言编码器 ──┤
3D模态 ──→ 3D编码器 ──┘
(点云/网格)
```
#### 空间推理任务类型
| 任务 | 输入 | 输出 | 示例 |
|------|------|------|------|
| 空间问答 (Spatial QA) | 图像 + 问题 | 文字答案 | "这栋建筑有几层?" |
| 空间关系描述 | 3D场景 | 关系三元组 | (树, 在...前面, 建筑) |
| 导航指令 | 语言指令 | 路径/动作 | "走到窗边左转" |
| 场景变化检测 | 两个时刻的场景 | 变化描述 | "左侧新增了一棵树" |
### 场景理解
场景理解是对一个完整空间的多层次分析:
```
场景理解三层次:
语义理解 (Semantic)
┌─────────────────────────────────────────────┐
│ 这是什么?每个部分的功能是什么? │
│ "这是客厅" "那是厨房" "这是走廊" │
└─────────────────────────────────────────────┘
几何理解 (Geometric)
┌─────────────────────────────────────────────┐
│ 空间的几何属性是什么? │
│ 面积、高度、距离、角度、曲率 │
└─────────────────────────────────────────────┘
关系理解 (Relational)
┌─────────────────────────────────────────────┐
│ 物体之间的关系是什么? │
│ A在B的上方、C连接D、E包围F │
└─────────────────────────────────────────────┘
```
#### 具体任务
- **语义分割**:每个区域的功能标注(居住、商业、绿地...)
- **布局估计**:房间的结构(墙壁、门窗位置)
- **物体关系图**:构建场景中物体之间的空间关系图
```
场景图 (Scene Graph):
[桌子] ──在上面──→ [电脑]
│ │
在旁边 连接到
↓ ↓
[椅子] [显示器]
在下面
[地毯]
```
### 大型空间模型
大型空间模型 (Large Spatial Models) 是一个新兴研究方向,旨在将大语言模型的推理能力与空间数据相结合。
```
大语言模型 (LLM): 擅长语言理解与推理
+
空间数据/模型: 擅长空间感知与几何计算
大型空间模型: 能理解和推理空间信息
类比:
LLM 是"能说话的大脑"
视觉模型是"能看的眼睛"
大型空间模型是"能理解空间的身体"
```
#### 代表性工作
| 方向 | 代表工作 | 描述 |
|------|----------|------|
| 3D-LLM | 3D-LLM (2023) | 将3D场景编码后输入LLM进行推理 |
| 空间问答 | SQA3D (2023) | 基于3D场景的问答基准 |
| 具身导航 | CLIPORT (2022) | 语言指导的机器人操作 |
| 场景生成 | SceneCraft (2024) | LLM驱动的场景布局生成 |
### GIS + AI:智能地理分析
地理信息系统 (Geographic Information System, GIS) 是空间设计的核心工具。AI正在重塑GIS的分析能力。
```
传统GIS:
数据采集 → 存储 → 可视化 → 人工分析
AI增强GIS:
数据采集 → 自动标注 → 智能分析 → 预测模拟 → 决策支持
↑ ↑ ↑
深度学习 空间推理 时空预测
```
#### AI+GIS的典型应用
| 应用场景 | AI技术 | 设计意义 |
|----------|--------|----------|
| 地物分类 | 语义分割 | 自动提取建筑、道路、水体 |
| 城市形态分析 | 深度学习 | 自动识别街区类型和肌理 |
| 地形分析 | 点云分割 | 坡度、坡向、汇水分析 |
| 变化检测 | 孪生网络 | 监测城市扩张和土地利用变化 |
| 选址分析 | 多因子评价 | AI辅助最优选址决策 |
| 交通模拟 | 图神经网络 | 预测交通流量和拥堵 |
### 数字孪生的演进
数字孪生 (Digital Twin) 是空间智能的终极目标——在数字世界中完整复制物理空间。
```
数字孪生的四个层次:
1. 几何孪生 (Geometric Twin)
┌───────────────────────────────────┐
│ 精确的3D几何模型 │
│ 例: 建筑BIM模型、城市3D白模 │
│ 静态的形状与空间关系 │
└───────────────────────────────────┘
2. 物理孪生 (Physical Twin)
┌───────────────────────────────────┐
│ 叠加物理属性与仿真 │
│ 例: 结构力学模拟、日照分析 │
│ 可以模拟物理过程 │
└───────────────────────────────────┘
3. 行为孪生 (Behavioral Twin)
┌───────────────────────────────────┐
│ 实时数据驱动的动态模型 │
│ 例: 实时人流监测、能耗数据 │
│ 反映当前状态和行为模式 │
└───────────────────────────────────┘
4. 认知孪生 (Cognitive Twin)
┌───────────────────────────────────┐
│ 具备推理和决策能力 │
│ 例: AI分析异常、推荐优化方案 │
│ 能"思考"和"建议" │
└───────────────────────────────────┘
```
#### 设计领域的数字孪生案例
- **建筑数字孪生**:从BIM模型到实时运维管理,结合IoT传感器数据监测建筑健康状态
- **城市数字孪生**:新加坡Virtual Singapore项目,完整的城市级数字孪生平台
- **景观数字孪生**:结合生态模型模拟植被生长、水文过程、生物多样性
### 思考与练习
1. 空间智能与2D图像理解的核心区别是什么?为什么空间推理需要三维信息?
2. 数字孪生的四个层次在设计实践中分别对应哪些具体工具和方法?
3. 设想一个"认知孪生"校园,它能做哪些事情?需要哪些技术支撑?
### 关键术语
| 中文 | 英文 | 说明 |
|------|------|------|
| 空间智能 | Spatial Intelligence | 理解和推理空间关系的能力 |
| 多模态推理 | Multi-modal Reasoning | 融合多种信息模态进行推理 |
| 场景图 | Scene Graph | 描述物体间关系的图结构 |
| 大型空间模型 | Large Spatial Model | 结合LLM与空间数据的模型 |
| 数字孪生 | Digital Twin | 物理空间的数字副本 |
| 地理信息系统 | GIS | 地理空间数据管理系统 |
### 延伸阅读
- [3D-LLM: Injecting 3D World into LLMs (Hong et al., 2023)](https://arxiv.org/abs/2307.12981)
- [SQA3D: Situated Question Answering in 3D Scenes (Ma et al., 2023)](https://arxiv.org/abs/2305.14086)
- [Microsoft Digital Twins](https://learn.microsoft.com/en-us/azure/digital-twins/)
---
# 5.5 设计应用
## 学习目标
- 了解3D AI在建筑设计、景观设计、城市设计等领域的综合应用
- 理解从数据采集到设计迭代的完整工作流
- 掌握实际项目中3D技术的选型思路
### 建筑:从概念到三维模型
#### 概念草图到3D模型
```
设计师手绘草图
↓ AI理解 (2D → 3D)
3D概念体量模型
↓ 参数化调整
优化方案
↓ BIM生成
完整建筑信息模型
```
**关键技术**
- 草图理解:深度学习识别建筑平面图中的墙体、门窗、空间
- 3D生成:Image-to-3D模型将草图转化为体量模型
- 参数化设计:AI根据设计约束(面积、高度、朝向)自动调整参数
#### 自动化BIM生成
```
无人机扫描既有建筑
↓ 3D重建 (NeRF/3DGS)
点云/网格模型
↓ 语义分割
识别: 墙体、楼板、梁柱、门窗
↓ 自动建模
Revit/ArchiCAD BIM模型
↓ 工程应用
结构分析 / 能耗模拟 / 施工管理
```
#### 设计迭代辅助
```
设计约束: 面积≥500m², 层数≤6, 日照≥2h/天
AI生成多个满足约束的体量方案
设计师选择并微调
AI实时反馈: 容积率、日照、风环境
```
### 景观:从地形到生态
#### 地形分析
```
无人机航拍
↓ 摄影测量 / LiDAR
DEM (数字高程模型)
↓ AI地形分析
├── 坡度分级图
├── 坡向分析图
├── 汇水流域图
└── 视域分析图
```
#### 植被模拟
```
当前场地点云
↓ 3D语义分割
识别现有植被(树种、冠幅、高度)
↓ 生长模型 + AI预测
模拟5年/10年/20年后的植被状态
辅助种植设计决策
```
#### 视廊分析
```
3D城市模型 + 观察点
↓ 视线追踪算法
计算每个区域的可见度
↓ 生成视域图 (Viewshed)
├── 确定最佳观景点
├── 保护重要景观视廊
└── 评估新建建筑对景观的影响
```
### 城市设计:数字孪生城市
#### 从无人机航拍到3D城市模型
**完整工作流案例**
```
Step 1: 数据采集
无人机搭载相机/LiDAR
覆盖1km²区域,重叠率70%+
Step 2: 3D重建
照片 → SfM → 稀疏点云
→ MVS → 稠密点云
→ 网格重建 → 纹理映射
或: 照片 → 3DGS → 实时渲染场景
Step 3: 语义理解
点云/网格 → 3D语义分割
识别: 建筑、道路、植被、水体、地面
Step 4: 城市分析
├── 城市形态: 建筑密度、高度分布、街区肌理
├── 开放空间: 绿地可达性、公共空间品质
├── 交通网络: 道路连通性、步行友好度
└── 微气候: 日照、风环境、热岛效应
Step 5: 决策支持
方案对比模拟 → 可视化呈现 → 辅助规划决策
```
#### 城市形态分析
```
3D城市模型
↓ AI自动提取
建筑轮廓 + 高度 + 功能
↓ 形态学分析
├── 街道宽高比 (D/H)
├── 建筑密度 (FAR)
├── 天际线分析
└── 街区类型分类
城市设计导则制定
```
### 室内设计:从扫描到设计
#### 室内设计全流程
```
Step 1: 房间扫描
手机/深度相机扫描
实时3D重建 (如 LiDAR iPad/iPhone)
完整室内点云/网格
Step 2: 场景理解
3D语义分割
识别: 墙壁、地面、天花板、门窗、现有家具
自动生成户型图 + 尺寸标注
Step 3: 设计生成
输入: 户型图 + 风格偏好 + 预算
↓ AI辅助
生成多个布局方案 (2D + 3D)
材质搭配 + 灯光设计
Step 4: 可视化与迭代
实时3D渲染 / VR预览
设计师/客户反馈 → AI调整
最终方案
```
### 工业设计:逆向工程与再设计
#### 产品扫描到再设计
```
现有产品 (如: 经典椅子)
↓ 3D扫描 (结构光/激光)
高精度点云/网格
├── 逆向工程: 提取设计参数
│ 曲面分析、人机工程参数
├── 缺陷检测: 识别磨损/变形区域
│ 为改良设计提供依据
└── AI再设计: 基于原始形态生成变体
"保留经典轮廓,增加人体工学支撑"
```
```
3D扫描模型
↓ AI分析
特征提取 (曲率、对称性、风格特征)
↓ 参数化表示
↓ 生成式设计
新的变体方案
├── 拓扑优化 (减重、增强)
├── 可制造性分析 (3D打印/CNC)
└── 风格迁移 (保留功能,改变风格)
```
### 综合案例:从无人机航测到3D城市模型
以下代码展示一个简化但完整的城市3D重建工作流:
```python
import open3d as o3d
import numpy as np
# ===== Step 1: 加载无人机航测生成的点云 =====
# 实际项目中由COLMAP/OpenMVS/Pix4D等工具从照片生成
pcd = o3d.io.read_point_cloud("aerial_survey.ply")
# ===== Step 2: 点云预处理 =====
# 下采样 (减少点数,保留结构)
pcd_down = pcd.voxel_down_sample(voxel_size=0.05)
# 去除噪声点 (统计滤波)
pcd_clean, _ = pcd_down.remove_statistical_outlier(
nb_neighbors=20, std_ratio=2.0
)
# 估计法向量
pcd_clean.estimate_normals(
search_param=o3d.geometry.KDTreeSearchParamHybrid(
radius=0.1, max_nn=30
)
)
print(f"处理后点数: {len(pcd_clean.points)}")
# ===== Step 3: 地面分割 (简化版) =====
points = np.asarray(pcd_clean.points)
# 用高度阈值简单分割(实际项目用CSF等算法)
min_z = points[:, 2].min()
ground_mask = points[:, 2] < min_z + 0.5 # 地面点
building_mask = points[:, 2] >= min_z + 1.5 # 建筑点
ground_pcd = pcd_clean.select_by_index(
np.where(ground_mask)[0]
)
building_pcd = pcd_clean.select_by_index(
np.where(building_mask)[0]
)
# 给不同类别上色
ground_pcd.paint_uniform_color([0.6, 0.8, 0.6]) # 绿色=地面
building_pcd.paint_uniform_color([0.7, 0.7, 0.9]) # 蓝色=建筑
# ===== Step 4: 可视化 =====
o3d.visualization.draw_geometries(
[ground_pcd, building_pcd],
window_name="城市3D模型 - 地面(绿)+建筑(蓝)",
width=1200, height=800
)
# ===== Step 5: 基础分析 =====
print(f"\n===== 场景分析 =====")
print(f"地面点: {np.sum(ground_mask)}")
print(f"建筑点: {np.sum(building_mask)}")
print(f"建筑最高点: {points[building_mask, 2].max():.1f}m")
print(f"场景范围: {points.max(axis=0) - points.min(axis=0)}")
# ===== Step 6: 表面重建 (可选) =====
# 使用Poisson重建将点云转为网格
mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(
pcd_clean, depth=8
)
# 保存网格模型
o3d.io.write_triangle_mesh("city_model.obj", mesh)
print("城市模型已保存为 city_model.obj")
```
### 各领域3D技术选型参考
| 设计领域 | 首选3D表示 | 推荐技术 | 典型工具 |
|----------|------------|----------|----------|
| 建筑 | 网格 + BIM | 3DGS/NeRF重建 | Pix4D, RealityCapture |
| 景观 | 点云 + DEM | LiDAR + 语义分割 | CloudCompare, LAStools |
| 城市设计 | 网格 + 体素 | 倾斜摄影测量 | Cesium, CityEngine |
| 室内设计 | 网格 | RGB-D扫描 | Matterport, Polycam |
| 工业设计 | 网格 | 结构光扫描 | Artec, Shining 3D |
### 思考与练习
1. 如果你需要为一个历史街区制定保护规划,会采用哪种3D数据采集和重建方案?说明理由。
2. 比较NeRF和3DGS在建筑外观重建中的优缺点,什么场景下选哪种?
3. 设计一个利用3D扫描和AI技术辅助室内改造的完整方案,包括数据流、技术选型和用户交互。
---
## 思考与练习
1. **表示方式选择**:针对以下三种场景,分别选择最合适的3D表示方式(点云、网格、体素或深度图),并说明理由:(a) 自动驾驶中的实时障碍物检测;(b) 游戏中的角色建模;(c) 室内装修方案的VR预览。
2. **技术路线对比**NeRF和3D Gaussian Splatting分别代表了隐式和显式的场景表示路线。请从设计应用的角度分析:哪些设计场景更适合NeRF,哪些更适合3DGS?未来两者会融合还是分化?
3. **空间智能畅想**:设想你正在设计一个"AI空间设计师助手",它能理解建筑平面图、3D模型和自然语言描述。请描述这个系统的核心功能模块,以及每个模块需要用到本章学到的哪些技术。
## 关键术语
| 中文 | 英文 | 说明 |
|------|------|------|
| 点云 | Point Cloud | 三维坐标点的集合 |
| 网格 | Mesh | 顶点、边、面组成的多面体 |
| 体素 | Voxel | 三维空间规则网格单元 |
| 深度图 | Depth Map | 存储距离信息的二维图像 |
| 激光雷达 | LiDAR | 激光测距三维传感器 |
| 置换不变性 | Permutation Invariance | 输入顺序不影响输出 |
| 运动恢复结构 | Structure from Motion (SfM) | 从多视角照片恢复3D结构 |
| 多视图立体匹配 | Multi-View Stereo (MVS) | 稠密3D重建方法 |
| 神经辐射场 | NeRF | 用MLP隐式表示三维场景 |
| 体渲染 | Volume Rendering | 沿光线积分合成图像 |
| 三维高斯溅射 | 3D Gaussian Splatting | 用高斯椭球体显式表示场景 |
| 位置编码 | Positional Encoding | 提升高频细节的编码方法 |
| 空间智能 | Spatial Intelligence | 理解和推理空间关系的能力 |
| 场景图 | Scene Graph | 描述物体间关系的图结构 |
| 数字孪生 | Digital Twin | 物理空间的完整数字副本 |
| 地理信息系统 | GIS | 地理空间数据管理系统 |