WSL2下复现FoundationPose
1.准备工作
下载仓库
1 | git clone https://github.com/NVlabs/FoundationPose.git |
下载权重
前往此处下载权重,放在weights/目录下。
下载测试数据集
前往此处下载测试数据,解压到demo_data/目录下。
下载训练数据(可选)
如果要自己train的话,前往此处下载大规模训练数据
下载经过预处理的参考视图(可选)
如果要跑model-free的少样本学习版本, 前往此处下载,解压到demo_data/目录下。
下载YCB-Video数据集(可选)
如果需要YCB-Video数据集,这是一个200G+的数据集,BOP版做了筛选,在100G左右,前往此处下载,解压到demo_data/目录下。
2.环境配置
安装eigen3
1 | sudo apt install libeigen3-dev |
安装Conda
……
安装Cuda
见另一篇博客**《WSL下配置Cuda》**
创建Conda环境
1 | conda create -n foundationpose python=3.9 |
安装依赖
Step1.
把requirements.txt 文件原来的 torch 、torchvision、torchaudio先注释一下,手动安装
1 | pip install torch==2.4.0 torchvision==0.19.0 torchaudio==2.4.0 --index-url https://download.pytorch.org/whl/cu124 |
Step2.
1 | python -m pip install -r requirements.txt |
Step3.
1 | python -m pip install --quiet --no-cache-dir git+https://github.com/NVlabs/nvdiffrast.git |
如果下载速度慢或网络卡顿,可以先手动下载到本地后安装
1
2
3
4
5
6
7
8 # 下载源码
git clone https://github.com/NVlabs/nvdiffrast.git
# 进入目录
cd nvdiffrast
# 用 pip 安装(本地路径)
python -m pip install --no-cache-dir .
Step4.
1 | python -m pip install --quiet --no-cache-dir kaolin==0.16.0 -f https://nvidia-kaolin.s3.us-east-2.amazonaws.com/torch-2.4.0_cu124.html |
Step5.
1 | conda install https://anaconda.org/pytorch3d/pytorch3d/0.7.8/download/linux-64/pytorch3d-0.7.8-py39_cu121_pyt241.tar.bz2 |
安装PyTorch3D 这里也是安装和pytorch对应的具体看这个PyTorch3D 安装-CSDN博客 ,pytorch3d官网地址install pytorch3d version: pytorch3d
Step6.
1 | CMAKE_PREFIX_PATH=$CONDA_PREFIX/lib/python3.9/site-packages/pybind11/share/cmake/pybind11 bash build_all_conda.sh |
报错:
1
2 error: #error You need C++17 to compile PyTorch
error: #error C++17 or later compatible compiler is required to use PyTorch.原因是当前的nvcc编译
.cu文件时使用了 -std=c++14, Pytorch C++扩展必须使用C++ 17 或更高版本。解决方法是修改编译参数将C++ 14改为C++ 17。首先清理之前的构建文件
1
2 cd FoundationPose/bundlesdf/mycuda
rm -rf build *.egg-info确保 C++17 编译(必须),设置 GPU 架构(可选,但推荐)。修改
mycuda下setup.py
1
2
3
4
5
6
7
8
9 c_flags = ['-O3', '-std=c++17']
nvcc_flags = [
'-O3',
'-std=c++17',
'-U__CUDA_NO_HALF_OPERATORS__',
'-U__CUDA_NO_HALF_CONVERSIONS__',
'-U__CUDA_NO_HALF2_OPERATORS__',
'-gencode', 'arch=compute_89,code=sm_89' # 针对 RTX 4060
]重新编译
1 python setup.py build_ext --inplace或者
1 pip install -e . --use-pep517过时警告:
1
2
3 easy_install command is deprecated
setup.py install is deprecated
Unknown distribution option: 'extra_cflags'当前 PyTorch/CUDA 扩展依赖的
setup.py使用了过时方法。pip 25+ 会对setup.py develop出现错误。解决方法是使用 PEP 517/518 的方式:
1 pip install -e . --use-pep517或直接通过
python setup.py build_ext --inplace编译扩展,而不是 develop。
3.测试Demo
1 | python run_demo.py |
报错:
1 c++: fatal error: Killed signal terminated program cc1plus这种情况一般是 编译过程中被系统杀掉了,最常见原因是 内存不足(尤其是 8GB GPU 或内存较小的机器),而不是代码本身的问题。解决方法是降低 CPU 内存占用,或者修改
TORCH_CUDA_ARCH_LIST,避免编译所有架构。
1
2 export MAX_JOBS=1 # 方法1
export TORCH_CUDA_ARCH_LIST="8.9" # 方法2 对应你的 RTX 4060然后运行
1 python run_demo.py报错:
1 ImportError: ... libstdc++.so.6: version `GLIBCXX_3.4.32' not found意思是 系统的 libstdc++ 版本太旧,无法满足
nvdiffrast插件编译时的要求。这个问题通常发生在 Linux 系统自带的 GCC/标准库版本较旧,而 PyTorch 或 nvdiffrast 需要较新的GLIBCXX。检查系统当前libstdc++版本,如果没有
GLIBCXX_3.4.32,说明版本过低。
1 strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX如果有可能是 Python/conda 环境没使用到系统的 libstdc++,或者 nvdiffrast 在编译时链接到了一个旧版本的 libstdc++。
确保conda 优先使用系统 libstdc++
1
2 export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH然后直接运行
1 python run_demo.py
4.自制数据集
数据集文件夹格式
1 | . |
注意:rgb文件夹下的彩色最好是png,否则要修改读取图片的代码
5.Demo解析
1 | import os |
引入必要模块
1 | if __name__=='__main__': |
参数解析器,支持从命令行传参
1 | parser.add_argument('--mesh_file', type=str, |
定义命令行参数:
- mesh_file:物体 3D 模型路径
- test_scene_dir:测试场景(包含 RGBD 数据)的目录
- est_refine_iter:初始估计 refinement 次数
- track_refine_iter:跟踪 refinement 次数
- debug:调试模式(等级越高保存的中间结果越多)
- debug_dir:调试文件输出目录
1 | set_logging_format() |
设置日志格式和随机种子,保证实验可复现。
1 | mesh = trimesh.load(args.mesh_file) |
加载 3D 网格模型(用 trimesh 库)
1 | debug = args.debug |
清空 debug 文件夹,并新建保存可视化结果的子目录
1 | to_origin, extents = trimesh.bounds.oriented_bounds(mesh) |
计算 mesh 的 有向包围盒 (OBB),得到:
to_origin: mesh 对齐到原点的变换矩阵把
mesh变换到一个新的坐标系里,在这个坐标系下,物体的 OBB 就是 轴对齐的(盒子中心在原点,边和 XYZ 轴平行)。举例:如果原来的 mesh 歪着放,
to_origin就是“把它摆正、放到中心”的变换。extents: 包围盒的长宽高[lx, ly, lz]
bbox: 最终的 3D 包围盒坐标(min/max)一个最大点和一个最小点确定3D包围盒
1 | scorer = ScorePredictor() |
初始化关键组件:
ScorePredictor:评分网络(用于评估姿态的好坏)。PoseRefinePredictor:位姿 refinement 网络。dr.RasterizeCudaContext():基于 CUDA 的可微分渲染器(用来渲染和对比 RGBD)。
1 | est = FoundationPose(model_pts=mesh.vertices, |
创建 FoundationPose 实例,传入模型点云、法向量、网格和网络组件。
1 | reader = YcbineoatReader(video_dir=args.test_scene_dir, |
数据读取器(这里针对 YCB-InEOAT 数据集),返回 RGB、深度、mask 等
1 | for i in range(len(reader.color_files)): |
遍历每一帧,读取 RGB 和深度。
1 | if i==0: |
在第一帧,调用 register(): 输入相机内参 K、RGB、深度图和物体掩膜,估计物体的初始 6D 姿态。
if debug>=3:
m = mesh.copy()
m.apply_transform(pose)
m.export(f'{debug_dir}/model_tf.obj')
xyz_map = depth2xyzmap(depth, reader.K)
valid = depth>=0.001
pcd = toOpen3dCloud(xyz_map[valid], color[valid])
o3d.io.write_point_cloud(f'{debug_dir}/scene_complete.ply', pcd)
如果 debug≥3:
- 导出变换后的 mesh。
- 保存完整的点云(场景点云 + RGB 颜色)。
1 | else: |
后续帧调用 track_one(),根据上一帧的结果进行跟踪。
os.makedirs(f'{debug_dir}/ob_in_cam', exist_ok=True)
np.savetxt(f'{debug_dir}/ob_in_cam/{reader.id_strs[i]}.txt', pose.reshape(4,4))
把每一帧的 4×4 位姿矩阵保存为 txt 文件。、
if debug>=1:
center_pose = pose@np.linalg.inv(to_origin)
vis = draw_posed_3d_box(reader.K, img=color, ob_in_cam=center_pose, bbox=bbox)
vis = draw_xyz_axis(color, ob_in_cam=center_pose, scale=0.1, K=reader.K, thickness=3, transparency=0, is_input_rgb=True)
cv2.imshow('1', vis[...,::-1])
cv2.waitKey(1)
如果 debug≥1:
将 3D 包围盒投影到图像上。
画出物体坐标系三轴。
用 OpenCV 实时显示结果。
if debug>=2:
os.makedirs(f’{debug_dir}/track_vis’, exist_ok=True)
imageio.imwrite(f’{debug_dir}/track_vis/{reader.id_strs[i]}.png’, vis)
如果 debug≥2:保存跟踪可视化结果到 track_vis 文件夹。