1. 环境准备:避坑从系统配置开始
第一次用OpenMVG+OpenMVS重建自己的照片集时,我在环境配置上栽了不少跟头。这里分享下实测可用的方案:推荐使用Ubuntu 20.04 LTS系统,内存建议16GB以上(处理50张手机照片至少需要8GB)。显卡不是必须的,但如果有NVIDIA显卡并安装CUDA,后续密集点云处理能快3-5倍。
安装依赖时最容易出现libjpeg版本冲突。建议按这个顺序操作:
# 先安装OpenMVS的依赖 sudo apt-get install -y git cmake libpng-dev libjpeg-dev libboost-iostreams-dev libboost-program-options-dev libboost-system-dev libboost-serialization-dev libopencv-dev libcgal-dev libglfw3-dev libomp-dev关键提示:一定要先装OpenMVS再装OpenMVG!我试过反过来操作,结果在稠密重建阶段出现诡异的图像加载失败,最后发现是两个库的libjpeg版本不兼容导致的。
编译OpenMVG时记得修改CMakeLists.txt:
# 找到openMVG/src/CMakeLists.txt # 注释掉以下段落避免使用内部jpeg库 #if (DEFINED OpenMVG_USE_INTERNAL_JPEG) # message(STATUS "LIBJPEG (internal)") #else() # message(STATUS "LIBJPEG (external)") #endif()2. 数据采集的黄金法则
用手机拍了一组校园雕塑的照片,结果重建出来全是碎片。后来发现是拍摄方式有问题,这里总结几个实测有效的技巧:
- 拍摄动线:像削苹果皮一样环绕物体拍摄,相邻照片重叠度要超过60%。我习惯先水平绕一圈(每15°拍一张),再上下倾斜30°绕第二圈
- 避坑要点:
- 避免纯色墙面背景(特征点不足)
- 关闭美颜滤镜(会破坏纹理细节)
- 固定曝光参数(自动曝光会导致颜色不一致)
- 手机参数:用专业模式锁定焦距,iPhone用户可以用Halide这类APP。我的华为P40 Pro设置参数:焦距5.58mm(后面会用到这个值)
实测案例:处理20张1280x720照片只需3分钟,但同样数量的4000x3000照片要25分钟。建议手机拍摄分辨率设为1080P足够
3. 相机参数处理实战
非专业相机的参数设置是个大坑。OpenMVG需要知道传感器宽度(sensor_width),这个值在官方数据库sensor_width_camera_database.txt里可能没有。以我的华为手机为例:
- 用exiftool查看照片元数据:
exiftool -Model -FocalLength -FocalLengthIn35mmFormat your_photo.jpg- 得到关键参数:
Model: CLT-AL00 Focal Length: 5.58 mm- 在
sensor_width_camera_database.txt末尾添加(计算公式:传感器宽度=35mm等效焦距/实际焦距*36):
CLT-AL00;5.94遇到报错Could not find sensor width for this camera时,可以临时用相近型号替代,但重建精度会下降约15%。
4. OpenMVG完整工作流
准备好/dataset/images文件夹后,按这个顺序执行:
# 1. 生成图像列表 openMVG_main_SfMInit_ImageListing -i /dataset/images -o /dataset/matches -d /usr/local/share/openMVG/sensor_width_camera_database.txt # 2. 计算特征点(AKAZE算法比SIFT快3倍) openMVG_main_ComputeFeatures -i /dataset/matches/sfm_data.json -o /dataset/matches -m AKAZE_FLOAT # 3. 特征匹配(-n Nearest匹配模式适合新手) openMVG_main_ComputeMatches -i /dataset/matches/sfm_data.json -o /dataset/matches -n NEAREST # 4. 增量式重建(全局重建需要更多内存) openMVG_main_IncrementalSfM -i /dataset/matches/sfm_data.json -o /dataset/reconstruction -m /dataset/matches常见报错解决方案:
Failed to load image XXX:检查路径深度不要超过3层Not enough matches found:回到步骤2改用SIFT算法- 卡在
Choosing initial pair:手动输入两个数字选择初始匹配对
5. OpenMVS稠密重建技巧
转换数据格式时要注意:
openMVG_main_openMVG2openMVS -i /dataset/reconstruction/sfm_data.bin -o /dataset/mvs/scene.mvs这三个步骤最吃硬件资源:
# 1. 稠密点云(显存不足加--resolution-level 2) DensifyPointCloud /dataset/mvs/scene.mvs # 2. 网格重建(CPU线程数设为核数-2) ReconstructMesh /dataset/mvs/scene_dense.mvs --threads 6 # 3. 纹理映射(内存不足时加--resolution-level 1) TextureMesh /dataset/mvs/scene_dense_mesh.mvs遇到内存爆炸怎么办?我总结的应急方案:
- 在
scene.mvs里降低resolution参数(默认1,改为2) - 用
split命令分割场景(适合大场景) - 虚拟内存大法(swap分区设置20GB以上):
sudo fallocate -l 20G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile6. 效果优化与可视化
用MeshLab查看scene_dense_mesh.ply时,可以:
- 过滤噪点:Filters > Cleaning and Repairing > Remove Isolated Pieces
- 平滑表面:Filters > Smoothing... > Laplacian Smooth
- 增强纹理:Filters > Texture > Parametric Texture Atlas
最后提醒:重建质量取决于最差的那张照片。有次我20张照片里混入一张模糊的,整个模型就崩了。建议先用openMVG_main_QualityEvaluation筛选不合格照片。