一个基于 Position Based Dynamics (PBD) 的肝脏物理仿真演示系统,支持实时交互、视频跟踪和 Web 界面控制。
- 🎯 物理仿真: 基于 PBD 的肝脏软组织物理仿真,支持多种材料预设
- 🎮 交互控制: 支持鼠标和键盘交互,实时操作肝脏模型
- 📹 视频跟踪: 集成 CoTracker 进行视频点跟踪
- 🌐 Web 界面: 提供 Gradio Web 界面,支持远程参数调整
- 🔧 边界约束: 支持边界投影约束和精细配准约束
- 💾 数据保存: 支持保存和加载仿真状态
- Python 3.10+
- Conda 环境管理工具
- 支持 OpenGL 的图形系统
# 创建 conda 环境(如果尚未创建)
conda create -n pyPBD python=3.10
conda activate pyPBD# 安装基础依赖
pip install pygame PyOpenGL numpy opencv-python pillow
# 安装 Gradio(用于 Web 界面)
pip install gradio
# 安装 pypbd(Position Based Dynamics 库)
# 请根据实际情况安装 pypbd 库# 切换到项目目录
cd liver_demo_refactored
# 测试模块导入
python test_imports.py# 激活 conda 环境
conda activate pyPBD
# 切换到项目目录
cd liver_demo_refactored
# 运行主程序
python main.py关键帧配准是将2D视频图像中的边界点与3D肝脏模型进行对齐的过程。在完成2D点和3D点的打点交互后,按照以下步骤进行关键帧配准:
前置条件:
- 已完成2D边界点标记(可通过按键
D在线绘制,或从inter.pkl文件加载) - 已完成3D网格边界点选择(通过按键
M进入选择模式,左键点击选择表面顶点)
配准步骤(按顺序执行):
-
按键
A- 执行刚性粗对齐(Rigid Coarse Alignment)- 功能:基于已标记的2D-3D对应点对,计算最优的刚体变换(旋转和平移)
- 作用:将3D肝脏模型粗略对齐到2D图像视角
- 输出:更新相机外参(旋转矩阵
R和平移向量t),使3D模型投影与2D图像大致对齐
-
按键
1- 切换相机参数对齐模式- 功能:启用/禁用相机参数对齐模式
- 作用:当启用时,3D模型渲染使用计算得到的相机参数,确保3D模型与2D投影对齐
- 提示:对齐模式下会自动调整缩放比例和视角,使3D模型与2D图像匹配
-
按键
Q- 计算并显示网格投影- 功能:将3D肝脏网格投影到2D屏幕空间,并切换投影可视化
- 作用:可视化3D模型在当前相机参数下的投影结果,用于验证对齐效果
- 提示:可以多次按
Q切换投影网格的显示/隐藏
-
按键
2- 建立精细配准约束(关键帧)- 功能:基于粗略对齐的结果,将2D边界点转换为投影射线,为3D点创建投影约束
- 作用:建立2D边界点到3D模型表面的约束关系,为后续的精细配准做准备
- 重要:这是关键帧配准的核心步骤,会保存约束关系供后续帧复用
-
按键
3- 切换投影射线可视化- 功能:显示/隐藏从相机位置到2D边界点的投影射线
- 作用:可视化2D点对应的3D投影射线,帮助理解配准过程
- 提示:可以检查投影射线是否穿过3D模型表面
-
按键
4- 切换约束射线可视化- 功能:显示/隐藏约束射线(用于精细配准的约束关系)
- 作用:可视化已建立的投影约束,显示3D点与投影射线的关系
-
按键
5- 启用/禁用投影约束- 功能:切换投影约束的启用状态(用于精细化配准)
- 作用:启用后,3D点会被拉向对应的投影射线,实现精细对齐
- 重要:必须启用此选项才能进行精细配准,约束会将3D模型表面点对齐到2D边界
-
按键
P- 暂停/继续仿真- 功能:暂停或继续物理仿真
- 作用:在配准过程中可以暂停仿真,观察对齐效果;继续后物理引擎会应用约束进行精细调整
配准流程总结:
打点完成 → A(粗对齐) → 1(启用对齐模式) → Q(查看投影) → 2(建立约束) → 3/4(可视化) → 5(启用约束) → P(开始精细配准)
注意事项:
- 默认情况下,程序启动时会自动从
data/cus/demo3/inter.pkl加载已保存的打点结果 - 也可以在线打点:按键
D绘制2D边界点,按键M选择3D网格边界点 - 关键帧配准完成后,约束关系会被保存,后续帧可以复用这些约束进行快速配准
完成关键帧配准后,可以对整个视频序列进行自动配准,实现3D肝脏模型随视频帧的动态变形。
前置条件:
- 已完成关键帧配准(完成上述步骤 A → 1 → Q → 2 → 3/4 → 5)
- 已准备好视频文件(支持格式:mp4, avi, mov, mkv)
配准步骤(按顺序执行):
-
Ctrl+V- 加载视频文件- 功能:打开文件选择对话框,选择要处理的视频文件
- 作用:加载视频并设置为背景图像,视频帧将作为配准的参考
- 提示:加载成功后,视频的第一帧会显示为背景,可以通过
Ctrl+P播放/暂停视频 - 支持格式:MP4, AVI, MOV, MKV 等常见视频格式
-
I- 初始化 TAP 跟踪器(注意:是单独的I键,不是Ctrl+I)- 功能:使用关键帧的2D边界点初始化 TAP (Tracking Any Point) 跟踪器
- 作用:建立点跟踪系统,用于在视频序列中自动跟踪关键帧标记的边界点
- 原理:TAP 会跟踪关键帧中的2D点,为后续每一帧提供对应的2D边界点位置
- 重要:必须使用关键帧配准中采样后的2D点(按键
2后生成),确保跟踪精度 - 提示:如果未完成关键帧约束建立,会使用原始2D点(向后兼容),但推荐先完成关键帧配准
-
Ctrl+S- 启动/停止动态配准循环- 功能:启动自动配准循环,对视频的每一帧执行 coarse-to-fine 配准
- 作用:自动处理视频序列,将3D肝脏模型对齐到每一帧的2D图像
- 工作流程:
- 使用 TAP 跟踪器获取当前帧的2D边界点
- 执行刚性粗对齐(Coarse Registration)
- 复用关键帧约束关系执行精细配准(Fine Registration)
- 提示:再次按
Ctrl+S可以停止配准循环 - 注意:配准循环启动后,视频会自动播放,系统会逐帧处理
-
5- 切换投影约束(控制配准模式)- 功能:启用/禁用投影约束,控制配准的刚性和柔性
- 启用约束(默认):进行柔性动态配准
- 3D模型会通过 PBD 物理引擎进行变形
- 模型表面点会被拉向投影射线,实现平滑的变形效果
- 适合模拟软组织的自然变形
- 禁用约束:进行刚性动态配准
- 只进行刚体变换(旋转和平移),不进行变形
- 3D模型保持形状不变,只改变位置和姿态
- 适合快速预览或刚性物体的跟踪
- 提示:可以在配准过程中动态切换,观察不同效果
动态配准流程总结:
关键帧配准完成 → Ctrl+V(加载视频) → I(初始化TAP) → Ctrl+S(启动循环) → 5(可选:切换配准模式)
视频控制快捷键:
Ctrl+P: 视频播放/暂停(注意:单独的P用于暂停物理仿真)Ctrl+Left或,: 上一帧Ctrl+Right或.: 下一帧N: 对当前帧执行单次配准(不启动循环)
注意事项:
- 动态配准会复用关键帧建立的约束关系,因此关键帧配准的质量直接影响后续帧的配准效果
- TAP 跟踪器需要足够的帧数才能开始跟踪(默认窗口大小为16帧)
- 如果视频帧率较高,可以调整
registration_loop_frame_interval参数跳过部分帧以提高性能 - 配准过程中可以随时按
P暂停物理仿真,观察当前帧的对齐效果 - 建议在配准前先检查关键帧的对齐质量,确保约束关系正确建立
程序启动后会自动启动 Gradio Web 界面(默认端口 7860),你可以通过浏览器访问:
- 本地访问: http://localhost:7860
- 网络访问: http://:7860
在 Web 界面中可以:
- 调整仿真参数(刚度、泊松比等)
- 控制边界约束组
- 暂停/继续仿真
- 调整渲染参数
LaporPyPBD/
├── liver_demo_refactored/ # 主程序目录
│ ├── main.py # 主程序入口
│ ├── config.py # 配置参数
│ ├── state.py # 全局状态
│ ├── physics.py # 物理仿真
│ ├── rendering.py # 渲染相关
│ ├── interaction.py # 交互处理
│ ├── constraints.py # 约束处理
│ ├── video_tracking.py # 视频跟踪
│ ├── gradio_interface.py # Web 界面
│ └── ... # 其他模块
├── cotracker/ # CoTracker 视频跟踪模块
├── data/ # 数据目录
│ └── cus/ # 自定义数据
│ └── demo3/ # 演示数据
├── pbd-demo.gif # 运行效果演示
├── render_tools.py # 渲染工具
└── lar_api_utils.py # API 工具
- config.py: 所有可配置参数,包括材料特性、仿真参数等
- state.py: 全局状态变量管理
- physics.py: PBD 物理仿真核心逻辑
- rendering.py: OpenGL 渲染相关函数
- interaction.py: 鼠标、键盘事件处理
- constraints.py: 边界约束和投影约束实现
- video_tracking.py: 视频跟踪和 TAP 跟踪功能
- model_builder.py: 模型构建(肝脏网格、地板等)
主要参数在 liver_demo_refactored/config.py 中配置:
- 材料预设:
MATERIAL_PRESET(1=软质, 2=中等, 3=硬质, 4=超软) - 肝脏刚度:
LIVER_STIFFNESS - 泊松比:
LIVER_POISSON_RATIO - 体积刚度:
LIVER_VOLUME_STIFFNESS - 边界投影刚度:
BOUNDARY_PROJECTION_STIFFNESS
默认数据位于 data/cus/demo3/ 目录,包括:
sofa_in/: 输入网格文件(.obj)sofa_out/: 输出变形结果inter.pkl: 边界约束数据
- 左键拖拽: 移动相机视角
- 右键拖拽: 旋转模型
- 滚轮: 缩放视图
- 左键点击(在特定模式下):
- 边界点绘制模式(
D): 在2D图像上标记边界点 - 网格点选择模式(
M): 选择3D网格表面顶点 - 交互模式: 拖拽3D模型进行交互
- 边界点绘制模式(
在进行关键帧配准之前,需要完成2D点和3D点的对应标记:
2D边界点标记:
- 按
D键进入边界点绘制模式 - 在2D图像(背景)上左键点击,标记边界点
- 可以标记多个点组,每组对应一个边界区域
- 再次按
D退出绘制模式
3D网格边界点选择:
- 按
M键进入网格边界点选择模式 - 在3D肝脏模型表面左键点击,选择对应的边界顶点
- 选择的点会自动与2D边界点建立对应关系
- 可以创建多个点组,每组对应一个2D边界点组
- 再次按
M退出选择模式 - 按
C清除当前组的选择
数据加载:
- 默认情况下,程序启动时会从
data/cus/demo3/inter.pkl自动加载已保存的打点结果 - 如果文件不存在或需要重新标记,可以使用上述在线打点功能
P: 暂停/继续仿真R: 重置模型到初始状态S: 保存当前状态L: 加载保存的状态T: 重置相机平移Space: 切换肝脏线框模式
A: 执行刚性粗对齐1: 切换相机参数对齐模式Q: 计算并显示网格投影2: 建立精细配准约束(关键帧)3: 切换投影射线可视化4: 切换约束射线可视化5: 启用/禁用投影约束
D: 进入/退出2D边界点绘制模式(左键点击绘制)M: 进入/退出3D网格边界点选择模式(左键点击选择表面顶点)C: 清除当前选择(在边界点选择模式下清除选中的点)
Ctrl+V: 加载视频文件(打开文件选择对话框)Ctrl+P: 视频播放/暂停(注意:单独的P用于暂停物理仿真)Ctrl+Left或,: 跳转到上一帧Ctrl+Right或.: 跳转到下一帧I: 初始化 TAP 跟踪器(使用关键帧的2D边界点)Ctrl+S: 启动/停止动态配准循环N: 对当前帧执行单次配准(不启动循环)
8: 调整肝脏透明度(循环增加)V: 切换速度场可视化(注意:Ctrl+V用于加载视频)
- 检查 conda 环境是否正确激活:
echo $CONDA_DEFAULT_ENV - 运行导入测试:
python liver_demo_refactored/test_imports.py - 检查父目录中是否存在
render_tools.py和lar_api_utils.py - 检查 pypbd 是否已正确安装:
python -c "import pypbd; print('OK')"
- 确保已安装 gradio:
pip install gradio - 检查端口 7860 是否被占用
- 查看控制台错误信息
请查看项目根目录的许可证文件(如有)。
欢迎提交 Issue 和 Pull Request!
