资讯详情

openSfM+MVSNet环境搭建与多视图三维重建实践

📅 2026/10/3 1:33:40 | 华诺云谱 👁 阅读
openSfM+MVSNet环境搭建与多视图三维重建实践
1. 项目概述这套流程到底在做什么最近在折腾多视图三维重建手上有一批用相机绕着物体拍的照片目标很明确把这些普通二维图像变成有真实空间形态的稠密点云。我选定的方案是openSfM MVSNet一个做稀疏重建和相机位姿估计一个做基于深度学习的稠密匹配组合起来刚好覆盖完整链路。这套方案在三维重建圈子里很常见但环境搭建的坑确实不少尤其是两个项目各自的依赖版本都比较敏感混在一起更容易踩雷。这篇文章就把我完整的搭建过程、关键命令、转换脚本和排错记录整理出来给同样在配置环境的人一个参考。1.1 多视图重建的两个关键阶段通常说的“从照片到点云”实际并不是一个程序一步到位的而是拆成两个阶段。第一个阶段是稀疏重建也叫运动恢复结构英文缩写SfM。它要做的事情是从一组图像中提取特征点匹配同名点然后估计每张照片的相机位姿和稀疏的三维点云。这个阶段解决的是“相机在哪里、朝哪个方向拍、场景基本骨架是什么”的问题。第二个阶段是稠密重建也叫多视图立体匹配英文缩写MVS。它在已知相机位姿的基础上对每个像素寻找跨视角的对应关系估算每个像素的深度最后融合成稠密点云。这个阶段解决的是“表面细节在哪里、几何结构长什么样”的问题。理解这两个阶段的分工非常重要因为后续的每个操作、每个报错几乎都能对应到这两个阶段之一。如果稀疏重建的相机位姿不准后面稠密重建做得再精细也只是白费功夫。反过来稀疏点云再准如果稠密匹配算法拉垮最终点云也会缺胳膊少腿。所以我选组合方案时会刻意把两个阶段的开源工具分开评估openSfM负责第一阶段MVSNet负责第二阶段。1.2 openSfM和MVSNet的具体分工openSfM是Mapillary开源的一个增量式SfM工具纯Python加C扩展轻量、易读、二次开发非常方便。它接受一个包含图片的文件夹输出相机内外参、稀疏点云和轨迹信息。和COLMAP相比openSfM的调参门槛低一些命令行更简洁导出JSON格式的相机参数也方便后续程序读取。MVSNet则是基于深度学习的MVS方法利用可微单应性变换构建代价体用3D卷积神经网络正则化回归出每个参考视图的深度图。相比传统的手工特征匹配方法它在弱纹理、反光区域和重复纹理场景下有更强的鲁棒性。这两个工具的角色可以打一个比方openSfM像是先给整个场景搭建一个“脚手架”确定每张照片拍摄时的空间位置MVSNet则像是“装修工人”踩着脚手架对墙面做精细测量补上每一个细节。没有脚手架装修工人不知道站在哪里干活没有装修工人脚手架信息再准也看不到完整表面。1.3 为什么选这套方案而不是其他组合社区里更常见的组合是COLMAP OpenMVSCOLMAP做稀疏重建和相机位姿估计OpenMVS做稠密重建。这套组合非常成熟但OpenMVS对编译和依赖的要求更高而且如果想在流程里插入深度学习方法OpenMVS的接口没有那么灵活。openSfM MVSNet的优势在于openSfM的JSON输出非常好解析MVSNet是独立的Python推理脚本中间只需要写一个转换脚本就能把相机参数对上。对于做算法研究和二次开发的人来说这套组合的透明度更高。另外MVSNet这一类基于深度学习的MVS方法已经逐渐成为稠密重建的主流方向。把openSfM作为前置位姿估计模块之后还可以很方便地换成MVSNet的后续改进版本比如CVP-MVSNet、CasMVSNet等。所以环境搭建这一步直接把两套工具链打通后面换模型只需要改推理脚本不用动整个环境。这也是我最终选定这条技术路线的核心原因。2. 环境搭建从零把依赖装齐环境搭建是整个流程里最劝退的部分。openSfM需要编译C扩展MVSNet依赖PyTorch和CUDA两者时钟版本交叉很容易出现今天装好A明天装B时把A的环境搞坏。我强烈建议全程使用conda虚拟环境Python版本锁定在3.8左右。太新的Python版本会让openSfM的旧依赖报错太老的版本又会限制PyTorch的安装。2.1 硬件与系统准备先讲硬件。我这次用的是一台Ubuntu 20.04服务器显卡是NVIDIA RTX 2080 Ti显存11GB。这个配置跑MVSNet有点紧需要控制输入图像的尺寸和源视图数量但至少能完整跑通流程。如果显存只有6GB建议把图像分辨率缩放到长边1000像素以内并且把视图数量控制在3张左右。CPU方面不需要太高规格openSfM的特征提取和多视图匹配阶段是纯CPU计算但可以多核并行我这边是8核16线程跑400张图片的匹配大概半小时。系统层面需要提前装好NVIDIA驱动和CUDA工具链。注意PyTorch的CUDA版本不需要和系统CUDA完全一致但驱动必须支持所需CUDA版本。用nvidia-smi查看驱动支持的最高CUDA版本然后选择对应的cudatoolkit即可。如果驱动太老会出现“CUDA driver version is insufficient”之类的报错。Ubuntu系统还需要安装一些基础编译工具包括build-essential、cmake、git等。2.2 安装基础依赖建议先更新系统软件源然后安装openSfM编译时需要的系统库。openSfM的核心依赖包括Ceres Solver、Boost、OpenCV、Eigen、gflags、glog。在Ubuntu 20.04下可以这样装sudo apt update sudo apt install -y build-essential cmake git sudo apt install -y libceres-dev libboost-all-dev libeigen3-dev sudo apt install -y libgflags-dev libgoogle-glog-dev libopencv-dev这里有个容易踩的坑libopencv-dev默认装的是OpenCV 4而openSfM的某些历史版本是基于OpenCV 3写的。如果编译时出现OpenCV头文件找不到或API不兼容的报错优先检查是不是OpenCV版本问题。我使用的openSfM版本较新兼容OpenCV 4所以这一步还算顺利。另外Ceres Solver建议使用系统自带的版本手动编译新版Ceres可能遇到莫名其妙的符号链接问题。2.3 创建conda虚拟环境接下来创建虚拟环境。我习惯把openSfM和MVSNet放在同一个环境里这样转换脚本可以同时引用两边的依赖不用频繁切换环境。命令如下conda create -n mvs python3.8 conda activate mvs激活环境后先升级pip再安装一些基础Python库pip install --upgrade pip pip install numpy scipy matplotlib opencv-python pillow pip install gdal pyproj networkx这里GDAL和pyproj主要是openSfM在处理地理参考影像时可能用到如果只是普通照片可以不装但建议还是装上避免后续读取EXIF GPS信息时报错。2.4 编译安装openSfMopenSfM的源码在GitHub上可以直接clone下来。我使用的是Mapillary官方仓库的最新master分支。安装命令如下git clone https://github.com/mapillary/OpenSfM.git cd OpenSfM pip install -r requirements.txt python setup.py build_ext --inplacesetup.py会在本地编译C加速模块。编译过程会输出大量日志看到“Finished processing dependencies for opensfm”之类的信息就说明成功了。如果不想手动编译也可以直接用pip安装pip install opensfm但官方PyPI包的更新通常滞后功能也没有源码版完整所以我推荐源码编译。编译完成后在OpenSfM目录下执行一下验证python -c import opensfm; print(opensfm ok)如果没报错说明Python包已经能正常导入。需要注意的是使用build_ext --inplace方式编译的模块运行时必须在OpenSfM根目录下或者把OpenSfM目录加入PYTHONPATH。否则会报找不到opensfm模块。2.5 安装MVSNet及其PyTorch依赖MVSNet的官方Torch实现是偏研究性质的代码依赖PyTorch但版本要求并不高。我使用的是GitHub上常见的MVSNet_pytorch分支可以搜索关键词“MVSNet PyTorch”找到。安装PyTorch前先确认本机的CUDA版本。比如驱动支持CUDA 11.3就可以安装对应版本的PyTorchpip install torch1.10.0cu113 torchvision0.11.0cu113 -f https://download.pytorch.org/whl/torch_stable.html这里有个细节MVSNet的旧代码在PyTorch 1.13之后可能会遇到torch.norm等接口行为变化的问题所以安装PyTorch 1.10左右比较稳。装完PyTorch后再安装MVSNet代码里需要的其他依赖pip install tensorboardX h5py tqdm然后clone MVSNet源码git clone https://github.com/你需要搜索的MVSNet_pytorch仓库.git cd MVSNet_pytorch具体仓库地址以你搜到的为准。clone下来后先别急着运行打开代码目录检查test.py或eval.py中import的模块是否都存在。我这次下载的版本需要的依赖很少主要就是PyTorch、numpy和PIL整体很轻。2.6 验证整体环境环境装完我建议先做一个最小验证准备一个只有三张图片的小数据集跑一遍openSfM的reconstruct然后再跑一次MVSNet的测试脚本。如果这两个命令都能通过说明环境基本没问题。验证openSfM最简单的方式是在OpenSfM目录下创建一个测试数据文件夹mkdir -p test_data/images # 把三张有重叠区域的jpg放进去 bin/opensfm run_all test_data这个命令会执行特征提取、匹配、建轨迹、增量重建和三角化最后在test_data目录下生成reconstruction.json和reconstruction.ply。能生成这两个文件openSfM环境就合格了。MVSNet的验证建议下载官方预训练权重跑一次DTU数据集的单样本测试或者用稍后转换好的自定义数据做推理。只要你看到深度图输出目录里有.pfm文件就说明MVSNet环境正常。3. 实操用openSfM跑出稀疏点云环境搞定之后开始真正干活。我用的是一个自己拍摄的雕塑数据集大概120张照片围绕物体环绕一圈每张照片的重叠率在70%左右。这种拍摄方式对SfM非常友好特征匹配的成功率高相机位姿恢复也更稳定。3.1 准备数据集openSfM要求的数据结构非常简单只需要一个包含图片的子文件夹。推荐组织方式如下dataset/ images/ image_001.jpg image_002.jpg ...图片支持jpg、png等常见格式。我在实际使用中发现图片分辨率过高反而会拖慢特征提取速度而且对结果精度提升有限。建议先用ImageMagick或Python脚本把长边缩到2000像素以内。openSfM内部自带下采样但输入太大会增加IO和内存开销。另外图片文件名最好连续编号且不要带特殊字符避免后面解析路径时出问题。在运行重建前先手工检查一遍照片是否有严重模糊、曝光是否均匀、是否有大面积的重复纹理。这些因素直接影响特征提取质量。如果照片里有大量的天空、白墙这类弱纹理区域建议在采集时尽量避免或者用掩码把无效区域删掉。3.2 执行特征提取与匹配进入openSfM目录后把自定义数据集路径传给bin/opensfm。最常用的一键命令是run_all它会按顺序执行所有步骤。但为了便于排错建议分步执行cd OpenSfM # 提取元数据包括焦距、GPS、方向等 bin/opensfm extract_metadata dataset # 检测特征点默认使用SIFT或AKAZE bin/opensfm detect_features dataset # 特征匹配生成图像之间的匹配关系 bin/opensfm match_features dataset特征提取阶段会在dataset目录下生成features文件夹每个图片对应一个.npz文件。如果发现特征点数量极少可以打开config.yaml调整feature_extraction中的参数比如增加max_features或者把feature_type从HAHOG改成SIFT。特征匹配阶段生成的matches文件夹记录了所有图像对的匹配结果如果某对图像匹配数很少说明重叠率不够或者视角变化太大。这里我特别想提醒一点openSfM默认的参数对普通手持相机照片比较友好但如果你的照片是从视频里抽帧得到的可能会因为运动模糊导致特征点质量差最好先做去模糊预处理。3.3 增量式重建与导出稀疏点云特征匹配完成后继续执行下一步# 构建轨迹把多视匹配连接起来 bin/opensfm create_tracks dataset # 增量式重建恢复相机位姿和稀疏点 bin/opensfm reconstruct dataset # 导出PLY点云 bin/opensfm export_ply datasetcreate_tracks会把所有图像间的匹配点连接成跨视角的轨迹相当于构建一个全局的特征对应关系图。reconstruct是核心步骤会从选定的初始图像对开始逐步添加新的图像估计相机位姿并三角化新点。整个过程中日志会不断打印新增了多少个点、注册了多少张图片。如果某个图片一直注册不上多半是特征匹配质量差或初始位姿估计失败。重建完成后dataset目录下会多出几个关键文件reconstruction.json包含每张图的相机内参、外参和稀疏三维点。reconstruction.ply可以直接用MeshLab或CloudCompare查看的稀疏点云。tracks.csv轨迹信息方便做调试。打开reconstruction.ply如果能看到一个轮廓清晰、没有明显断层的稀疏点云说明重建成功。如果点云扭曲、分离成多块通常需要回看图像采集质量或者调整reconstruct阶段的参数。3.4 参数调整经验openSfM的默认参数非常保守主要为了保证重建成功率但有时会导致点云过于稀疏。我这次在config.yaml里做了如下调整feature_extraction: feature_type: SIFT max_features: 5000 matching: lowes_ratio: 0.8 reconstruction: robust_min_match_count: 15max_features从默认值调高到5000可以增加特征点数量但也会增加匹配时间。lowes_ratio是描述子匹配的最近邻比值默认0.75我放宽到0.8让更多潜在匹配进入后续几何验证对弱纹理场景有帮助。robust_min_match_count控制三角化需要的最小匹配数降到15能减少点云空洞。这些参数没有绝对标准需要根据数据集反复试。我个人的习惯是先跑默认参数看收敛情况和点云效果再针对“哪里稀疏就调哪里”。不要一上来就疯狂调参很多问题出在图像质量上参数只是兜底手段。4. 实操用MVSNet生成稠密点云openSfM输出了稳定相机位姿接下来就是MVSNet的主场。MVSNet不是直接消费图像文件夹它要求把图像和相机参数组织成特定格式。这一步是整个流程中最容易出错的环节所以我拆开来讲。4.1 MVSNet的工作原理快速版MVSNet的核心思想是对某一张参考图像选择若干张源图像利用已知的相机内外参把源图像像素投影到参考图像的多个深度假设平面上形成一张代价体。这个过程很像“把不同视角的照片按深度方向排列看看在哪个深度上颜色最一致”。代价体经过3D卷积网络正则化后输出每个像素在深度方向上的概率分布取期望值就得到深度图。由于MVSNet依赖相机参数构造单应性变换所以相机参数必须非常精确。openSfM的稀疏重建结果如果出现漂移MVSNet输出的深度图就会有大面积噪声。这也是我前面强调要先检查稀疏点云质量的原因。4.2 数据格式转换MVSNet的标准输入数据格式参考DTU数据集目录结构大致如下mvs_input/ images/ image_000.jpg image_001.jpg cams/ image_000.txt image_001.txt pair.txt其中cams目录下每个文本文件存储对应图片的相机内外参和深度范围pair.txt指定每个参考图像使用哪些源图像。我写了一个Python脚本读取openSfM的reconstruction.json提取相机参数并转换成DTU格式import json import numpy as np import os with open(dataset/reconstruction.json) as f: recon json.load(f)[0] os.makedirs(mvs_input/images, exist_okTrue) os.makedirs(mvs_input/cams, exist_okTrue) shots recon[shots] points recon[points] # 这里根据实际图像名映射 for shot_id, shot in shots.items(): # 拷贝图像到mvs_input/images # 生成cam文件 cam_path os.path.join(mvs_input/cams, shot_id .txt) with open(cam_path, w) as f: # MVSNet读取的是世界到相机的变换 extrinsic np.eye(4) R np.array(shot[rotation]).T # 注意openSfM使用camera-to-world旋转 t np.array(shot[translation]) # 构造世界到相机矩阵 extrinsic[:3, :3] R.T extrinsic[:3, 3] -R.T.dot(t) # 内参 K np.array(shot[camera][projection]).reshape(3, 3) f.write(extrinsic\n) f.write(\n.join( .join(str(x) for x in row) for row in extrinsic)) f.write(\n\nintrinsic\n) f.write(\n.join( .join(str(x) for x in row) for row in K)) f.write(\n\n0.5 5.0\n) # depth_min depth_max这段脚本只是为了展示核心逻辑实际使用时要根据openSfM的JSON字段结构做适配。openSfM的rotation是相机坐标系到世界坐标系的旋转所以转换到世界到相机时需要做转置平移也需要相应变换。如果这一步搞反了MVSNet生成的深度图会整体错乱点云会出现严重的“鬼影”。关于depth_min和depth_max如果设置得过宽会增加深度搜索范围显存占用变大设置得过窄深度图会出现截断丢失远距离表面。我通常用稀疏点云的深度范围作为先验再往外扩30%作为搜索边界。4.3 运行深度估计转换好数据后进入MVSNet代码目录执行测试脚本。以常见的MVSNet_pytorch实现为例命令大概是python test.py --data_root mvs_input --output_folder output --model_path pretrained_model.ckpt实际参数名可能不同需要看代码里解析哪些参数。运行过程会逐张处理参考图像每张图像保存一个.pfm格式的深度图。如果GPU显存不足可以调整输入图像尺寸和源视图数。很多实现里--max_d控制深度采样数默认192--num_view控制源视图数量默认5。我把num_view改成3显存占用大幅下降点云质量没有明显下降。这里有一个很关键的经验MVSNet的输入图像尺寸需要和预训练模型匹配或者说要和模型训练时使用的图像尺度一致。如果直接塞入超大图模型可能因为感受野变化导致深度估计不稳定。我建议把图像长边缩放到约1600像素这也是很多预训练模型的默认设置。缩放后相机内参矩阵也需要按比例缩放否则内外参不一致会带来毫米级误差。4.4 深度图融合MVSNet输出的是一组参考深度图每张深度图都是某个视角下的深度估计还需要把它们融合到一个统一的三维点云里。融合工作常用开源工具fusibile完成。把MVSNet输出目录和相机参数目录传给fusibile后它会利用深度图的光一致性做筛选去除低置信度的像素再把符合条件的像素反投影到三维空间生成一个稠密点云。fusibile的编译也很简单一般CMake就能搞定git clone https://github.com/fusibile工具仓库.git cd fusibile mkdir build cd build cmake .. make运行命令大致是./fusibile -n mvs_input -f output -s 0.35参数s是置信度阈值越大保留的点越少但越干净。我通常从0.3开始试根据生成点云的噪声情况调整。如果雕塑表面有很多飞点就把s调高如果点云稀疏就把s降低。除了fusibile也可以用OpenMVS中的DensifyPointCloud做融合但输入格式需要额外转换不如fusibile直接。4.5 稠密点云后处理融合后的点云一般还带着不少离群点。我会用CloudCompare的“统计滤波”功能把偏离主表面超过一定距离的点滤除然后手动裁剪掉背景噪声。MVSNet在纯白色或纯黑色区域容易产生“点云雾霾”也就是物体表面附近分布着一层薄薄的噪声点这些点会在后续建模时严重影响表面重建质量必须处理干净。如果你发现整个点云有明显的“分层”或“重影”大概率不是后处理问题而是相机参数转换错误或MVSNet深度估计失效。这时候回看第4.2节的转换脚本优先检查旋转矩阵转置和平移向量方向。我自己就曾因为少做了一个转置导致所有深度图出现镜面对称式错误第一次看结果差点以为是显卡坏了。5. 典型问题与排查技巧这一节把我在搭建和调试过程中遇到的典型问题整理出来希望能帮你少走弯路。很多报错信息在GitHub issue里都能搜到但原因和解决方式往往藏在评论区这里做一个集中整理。5.1 openSfM编译报错openSfM编译最常见的报错是找不到Ceres或OpenCV头文件。这是因为系统默认库路径和项目预期不一致。解决办法有两个一是确认系统库已经安装二是在setup.py或CMake配置中显式指定库路径。另一种常见报错是编译过程中出现“undefined symbol”或“GLIBCXX版本不匹配”。这通常是因为conda环境里的libstdc版本太老而系统库依赖较新的版本。我当时的解决办法是更新conda环境里的libstdcconda install -c conda-forge libstdcxx-ng如果还不行就退回系统Python环境编译openSfM因为openSfM的Python扩展对conda的兼容性并不总是完美。编译成功后再用conda环境调用一般就不会冲突了。5.2 PyTorch与CUDA版本不匹配跑MVSNet时如果出现“CUDA error: no kernel image is available for execution on the device”基本就是PyTorch的CUDA版本和驱动不匹配。我建议先运行python -c import torch; print(torch.cuda.is_available())如果返回False优先重装PyTorch。不要盲目追求最新版MVSNet代码是几年前的PyTorch 1.10左右反而最省心。另外如果服务器上有多个CUDA环境注意LD_LIBRARY_PATH是否指向了错误的CUDA库。5.3 重建结果出现漂移或空洞openSfM重建的稀疏点云如果出现弯曲、分层或大范围空洞首先检查输入图像是否满足“足够重叠”和“连续视角”两个条件。环绕拍摄时相邻两张照片的角度差不要超过15度否则特征匹配很容易失败。其次检查config.yaml里matching的阈值放宽匹配阈值后重新跑match_features。如果是MVSNet输出深度图有大量黑色区域说明深度值落在设置的depth_min和depth_max范围之外。可以通过统计稀疏点云深度的分布缩小搜索范围让网络把注意力集中在有效区间。这个优化对显存和精度都有好处。5.4 显存不足显存不足是MVSNet新手最常遇到的问题。最直接的缓解方式是把图像分辨率缩到1200甚至800像素然后把num_view降到3。MVSNet的代价体尺寸是height × width × depth_samples × view_num每一项缩小一点显存占用都会指数级下降。如果还想再压榨性能可以尝试用半精度推理许多PyTorch实现都支持通过设置torch.set_grad_enabled(False)配合torch.cuda.amp来自动混精度。缺点是深度图的边缘可能稍微变糊但融合成点云后影响不大。如果彻底跑不动那就只能更换更大的显卡或者把场景切成多个子块分别重建后再配准拼接。5.5 问题速查表现象可能原因处理方式openSfM编译找不到Ceres系统库未装或路径不对安装libceres-dev检查CMake路径导入opensfm报错编译产物没有在当前目录在OpenSfM根目录运行或设置PYTHONPATHMVSNet运行时NaN学习率过大或预训练权重路径错误检查权重使用官方默认参数深度图整体镜像相机外参旋转矩阵方向不对检查世界到相机变换的转置点云噪声大深度图置信度低调高fusibile的s参数点云分层相机位姿有漂移回溯openSfM重建改善图像采集质量CUDA不可用PyTorch与驱动不匹配重装匹配的PyTorch版本特征点过少弱纹理或模糊调整为SIFT增大max_features6. 实操心得与后续扩展环境搭完、流程跑通之后我最大的感受是这套组合的上下限都取决于数据质量。openSfM对图像重叠率的要求非常高MVSNet对相机参数误差的容忍度又极低任何一个环节粗糙一点最后点云都会用肉眼可见的方式“回报”你。6.1 数据集拍摄建议如果条件允许尽量用固定焦距拍摄不要使用变焦镜头中途拉近拉远。openSfM虽然能估计焦距变化但误差会明显增大。光圈可以适当收小保证景深足够大避免边缘虚化影响匹配。拍摄时保持相邻两张照片的重叠率在70%以上环绕物体时尽量保持相机高度和角度一致。如果要拍一个大型场景最好分层拍摄保证不同高度的特征点都能被覆盖。光照条件也很重要。MVSNet在多视角颜色一致性上做假设如果同一表面在不同视角下因为阴影导致颜色差异太大深度估计就会失败。最好是阴天或均匀打光的环境避免太阳直射形成强阴影。6.2 从点云到网格的扩展稠密点云拿到手之后一般不会直接交付还要经过表面重建、纹理映射等步骤。我常用的路线是Poisson重建在CloudCompare或MeshLab里都能一键完成。Poisson重建对点云法线质量非常敏感而MVSNet融合出的点云自带法线估计可以直接用但如果有噪声点建议先做一次重采样让点云密度均匀。重建后的网格可能有一些闭合的伪表面需要手动裁剪。如果要做带纹理的模型把网格和原始图像导入Blender或专门的纹理映射工具比如MVS-Texturing就能生成带真实纹理的模型。这个扩展方向对建筑、文物的数字存档特别有价值。6.3 关于调试顺序的个人建议最后分享一个我踩过多次坑后形成的固定调试顺序先用30张以内的小数据集跑通openSfM和MVSNet全流程确认每个步骤的输出格式都正确再扩展到全量数据。全量数据跑一次可能要好几个小时如果中途发现相机参数格式错误浪费时间不说还容易让人怀疑人生。另外每次改动环境或代码前把当前能跑通的版本做好记录包括依赖版本号和关键参数。我一般会写一个environment.yml和requirements.txt即使几个月后回来继续做也能快速恢复环境。最终的效果是输入一堆照片输出一个可以拖进任何三维软件查看的稠密点云整个过程完全开源可控。这套组合虽然搭建过程有点折腾但跑通之后你会觉得一切都值得。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑