
计算机视觉图像处理机器学习【免费下载链接】opencv_contrib项目地址https://gitcode.com/gh_mirrors/ope/opencv_contrib点击查看免费下载导读本教程基于 opencv_contrib 仓库中sfmStructure From Motion模块的官方示例scene_reconstruction系统讲解如何利用reconstructionAPI 对一组真实拍摄的二维图像序列执行稀疏三维重建加载图片路径列表、运行基于 Libmv 的欧氏重建管线并借助 Viz 模块可视化估计出的三维点云与相机运动轨迹。读完本文你将掌握reconstruct()图像重载签名的调用方式、相机内参矩阵的构造方法、is_projective参数的语义以及如何在两个经典数据集Middlebury temple 与 Sagrada Familia上复现官方演示结果。本文主体内容源自 modules/sfm/tutorials/sfm_scene reconstruction/sfm_scene_reconstruction.markdown所有源码依据均可直接在本仓库中查阅验证。教程目标Goal本教程对应官方教程tutorial_sfm_scene_reconstruction核心任务包含三个步骤加载一个包含图像路径列表的文件运行Libmv 重建管线reconstruction API展示使用 Viz 获得的稀疏重建结果。这里的“稀疏重建sparse reconstruction”指的是从若干张二维图像中恢复一组稀疏的三维空间点点云以及每帧相机的位置与姿态而不是稠密重建。它是 SfM 管线的核心输出也是后续稠密重建、网格化与纹理映射的基础。环境准备SFM 模块依赖与安装前提在运行本教程示例之前需要先确认sfm模块被正确编译。根据 modules/sfm/README.md该模块仅面向 Linux/GNU 系统并依赖以下开源库依赖库版本要求必要性Eigen3.2.2 或更高必需Google Logglog0.3.1 或更高必需Google Flagsgflags—必需Ceres Solver—重建 API 依赖它完成部分 Bundle Adjustment 与点三角化Points Intersect若未安装reconstruct功能将被禁用推荐安装在 Ubuntu 上可先安装必需依赖sudo apt-get install libeigen3-dev libgflags-dev libgoogle-glog-devCeres Solver 的安装则需依次准备 CMake、glog/gflags、BLAS/LAPACKlibatlas-base-dev、Eigen3 以及可选的 SuiteSparse/CXSparse然后通过cmake .. make sudo make install完成编译安装。详细的安装步骤同样记录在 modules/sfm/README.md 中。一个需要特别注意的编译前提reconstructAPI 的定义被包裹在#if defined(CV_DOXYGEN) || defined(CERES_FOUND)条件编译块中见 modules/sfm/include/opencv2/sfm/reconstruct.hpp也就是说只有系统检测到 Ceres Solver 时场景重建接口才会被编译进 OpenCV。第一步准备图片路径列表文件重建 API 的图片重载签名接收的是一个“图片路径的容器”因此首先要准备一个文本文件其中每行存放一张待重建图片的完整路径。官方教程给出了文件内容的示例格式/home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2889.jpg /home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2890.jpg /home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2891.jpg /home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2892.jpg ...注意以上是教程作者机器上的绝对路径示例实际使用时请替换为你本地存放图像序列的路径。若图片与列表文件不在同一目录需要像示例程序那样将列表文件所在目录与相对文件名拼接成完整路径。示例程序scene_reconstruction.cpp中读取该文件的工具函数为getdir完整实现见 modules/sfm/samples/scene_reconstruction.cppstatic int getdir(const string _filename, vectorString files) { ifstream myfile(_filename.c_str()); if (!myfile.is_open()) { cout Unable to read file: _filename endl; exit(0); } else { size_t found _filename.find_last_of(/\\); string line_str, path_to_file _filename.substr(0, found); while ( getline(myfile, line_str) ) files.push_back(path_to_filestring(/)line_str); } return 1; }该函数逐行读取列表文件并把列表文件所在目录前缀拼接到每一行图片名之前从而得到可直接被imread使用的绝对路径。教程中同时还给出了一个更简化的等价逻辑仅逐行压入vectorstring二者本质一致实际仓库代码额外处理了相对路径拼接更贴合“列表文件与图片分散在不同目录”的真实场景。第二步构造相机内参矩阵 K在调用重建 API 之前示例通过命令行参数读取焦距与主点坐标构造 3×3 的相机内参矩阵见 modules/sfm/samples/scene_reconstruction.cpp// Parse the image paths vectorString images_paths; getdir( argv[1], images_paths ); // Build intrinsics float f atof(argv[2]), cx atof(argv[3]), cy atof(argv[4]); Matx33d K Matx33d( f, 0, cx, 0, f, cy, 0, 0, 1);对应的命令行参数为f以像素为单位的焦距focal length in pixelscx图像主点 x 坐标像素cy图像主点 y 坐标像素。内参矩阵形式为标准的针孔模型K [ f 0 cx 0 f cy 0 0 1 ]这里的 K 作为InputOutputArray传入重建 API它既是初始猜测值又会在重建过程中被内部精化refine后回写。运行结束后reconstruct会更新 K 中的焦距、主点与径向畸变参数。第三步调用 reconstruction API 进行稀疏重建核心调用代码非常简洁原样取自教程并对应仓库示例 modules/sfm/samples/scene_reconstruction.cppbool is_projective true; vectorMat Rs_est, ts_est, points3d_estimated; reconstruct(images_paths, Rs_est, ts_est, K, points3d_estimated, is_projective);参数说明images_pathsvectorString图片路径容器必须按图像序列顺序排列Rs_est输出每帧相机的 3×3 旋转矩阵集合ts_est输出每帧相机的 3×1 平移向量集合K输入/输出相机内参矩阵初始猜测最终被精化points3d_estimated输出估计出的三维点集合is_projective true表示按**射影重建projective reconstruction**模式运行。如果设为false从 modules/sfm/src/reconstruct.cpp 的源码可以看出仿射重建分支尚未实现会抛出CV_Error(Error::StsNotImplemented, Affine reconstruction not yet implemented)。随后打印重建统计信息cout \n----------------------------\n endl; cout Reconstruction: endl; cout endl; cout Estimated 3D points: points3d_estimated.size() endl; cout Estimated cameras: Rs_est.size() endl; cout Refined intrinsics: endl K endl endl;底层原理这条调用链背后发生了什么reconstruct(images, Rs, Ts, K, points3d, is_projective)走的是真实图像重载签名。与基于二维点轨迹的重载不同该签名在内部自动完成特征提取、匹配与轨迹构建使用DAISY 描述子从图像中提取并计算稀疏二维特征点使用FlannBasedMatcher对特征进行匹配构建跨帧的tracks轨迹结构调用 Libmv simple pipeline 完成欧氏重建。这一点在 modules/sfm/include/opencv2/sfm/reconstruct.hpp 与 modules/sfm/README.md 中均有明确说明。再深入一层所有reconstruct_*内部实现都汇入同一个模板函数reconstruct_()见 modules/sfm/src/reconstruct.cpp它设置了一组关键的 Libmv 管线参数// Initial reconstruction const int keyframe1 1, keyframe2 2; const int select_keyframes 1; // 启用自动关键帧选择 const int verbosity_level -1; // 静默 libmv 日志 // Refinement parameters const int refine_intrinsics SFM_REFINE_FOCAL_LENGTH | SFM_REFINE_PRINCIPAL_POINT | SFM_REFINE_RADIAL_DISTORTION_K1 | SFM_REFINE_RADIAL_DISTORTION_K2;随后构造libmv_ReconstructionOptions初始关键帧 1、2自动关键帧选择内参精化标志日志级别 -1与libmv_CameraIntrinsicsOptions采用SFM_DISTORTION_MODEL_POLYNOMIAL多项式畸变模型径向畸变系数初始为 0并实例化SFMLibmvEuclideanReconstruction后调用其run()方法PtrBaseSFM reconstruction SFMLibmvEuclideanReconstruction::create(camera_instrinsic_options, reconstruction_options); reconstruction-run(input, K, Rs, Ts, points3d);这些数据结构libmv_ReconstructionOptions、libmv_CameraIntrinsicsOptions、BaseSFM、SFMLibmvEuclideanReconstruction的完整定义位于 modules/sfm/include/opencv2/sfm/simple_pipeline.hpp。其中内参精化标志枚举为enum { SFM_REFINE_FOCAL_LENGTH (1 0), SFM_REFINE_PRINCIPAL_POINT (1 1), SFM_REFINE_RADIAL_DISTORTION_K1 (1 2), SFM_REFINE_RADIAL_DISTORTION_K2 (1 4) };libmv_ReconstructionOptions的默认构造参数为keyframe11, keyframe22, refine_intrinsics1, select_keyframes1, verbosity_level-1与reconstruct_()中的设置一致因此即使不显式配置重建管线也会默认启用自动关键帧选择与内参精化。仓库的单元测试也以同样的方式驱动该管线可作为正确用法的对照参考见 modules/sfm/test/test_simple_pipeline.cpplibmv_ReconstructionOptions reconstruction_options(keyframe1, keyframe2, refine_intrinsics, select_keyframes, verbosity_level); PtrSFMLibmvEuclideanReconstruction euclidean_reconstruction SFMLibmvEuclideanReconstruction::create(camera_instrinsic_options, reconstruction_options);第四步使用 Viz 展示点云与相机轨迹重建结果通过opencv2/viz.hpp的三维可视化窗口展示代码见 modules/sfm/samples/scene_reconstruction.cpp。首先创建三维窗口并设置窗口大小、位置与背景色viz::Viz3d window(Coordinate Frame); window.setWindowSize(Size(500,500)); window.setWindowPosition(Point(150,150)); window.setBackgroundColor(); // 默认黑色然后把估计出的三维点转换为Vec3f点云并用viz::WCloud以绿色渲染vectorVec3f point_cloud_est; for (int i 0; i points3d_estimated.size(); i) point_cloud_est.push_back(Vec3f(points3d_estimated[i])); if ( point_cloud_est.size() 0 ) { viz::WCloud cloud_widget(point_cloud_est, viz::Color::green()); window.showWidget(point_cloud, cloud_widget); }接着把每帧的旋转矩阵R与平移向量t组合成Affine3d形成相机路径vectorAffine3d path; for (size_t i 0; i Rs_est.size(); i) path.push_back(Affine3d(Rs_est[i],ts_est[i]));并使用WTrajectory绿色轨迹线与坐标系与WTrajectoryFrustums黄色相机视锥同时展示相机运动轨迹与每帧视锥最后把视点定位到第一帧相机位姿window.showWidget(cameras_frames_and_lines, viz::WTrajectory(path, viz::WTrajectory::BOTH, 0.1, viz::Color::green())); window.showWidget(cameras_frustums, viz::WTrajectoryFrustums(path, K, 0.1, viz::Color::yellow())); window.setViewerPose(path[0]);最后调用window.spin()进入交互循环按q键关闭窗口cout endl Press q to close each windows ... endl; window.spin();需要说明的是scene_reconstruction.cpp中的viz::WCloud、viz::WTrajectory、viz::WTrajectoryFrustums等组件来自opencv2/viz.hpp使用前请确认viz模块同样已编译进你的 OpenCV 构建。运行方式与官方实验结果在 OpenCV 二进制输出目录中按如下格式运行示例./example_sfm_scene_reconstruction path_to_file f cx cy其中path_to_file是图片路径列表文件的绝对路径f、cx、cy分别为焦距、主点 x 坐标、主点 y 坐标单位均为像素。实验一Middlebury temple 数据集使用 Middlebury 多视角数据集中的图像序列并指定相机参数焦距 800主点 (400, 225)./example_sfm_scene_reconstruction image_paths_file.txt 800 400 225输入图像序列如下运行后即可得到相机运动轨迹与稀疏三维重建结果实验二Sagrada Familia 数据集使用 Sagrada Familia巴塞罗那圣家堂图像序列并指定相机参数焦距 350主点 (240, 360)./example_sfm_scene_reconstruction image_paths_file.txt 350 240 360输入图像序列如下运行后得到相机运动轨迹与稀疏三维重建结果两个数据集的输入/输出对照图以及示例的完整截图均存放在仓库 modules/sfm/doc/pics 目录下可在本地复现后直接比对效果。Middlebury 序列来自多视角重建领域的公开基准数据集Sagrada Familia 序列出自 Penate Sanchez、Moreno-Noguer、Andrade Cetto 与 Fleuret2014关于低质量图像三维姿态估计的研究工作中所使用的数据集论文发表于 International Conference on 3D vision, 3DV。使用限制与注意事项根据 modules/sfm/include/opencv2/sfm/reconstruct.hpp 中对图像重载签名的文档说明以下限制直接影响实验成败务必遵守图像必须按序列顺序排列且相邻帧之间的拍摄位姿应尽量接近“each frame should be as close as possible to the previous and posterior”否则特征匹配与轨迹构建会失败当前 DAISY 特征实现只适用于 3~4 张图像的序列超出该范围时重建 API 可能无法给出可靠结果轨迹必须尽可能精确该 API 不处理离群点outliers对噪声与错误匹配非常敏感二维点轨迹版本的重载reconstruct(points2d, ...)同样要求nviews 2否则会触发断言失败若is_projective传false由于源码中仿射重建分支尚未实现会直接抛出“Affine reconstruction not yet implemented”的未实现异常。延伸阅读官方教程入口table_of_content_sfm.markdown其中还包含相机轨迹估计sfm_trajectory_estimation.markdown、重建结果导入sfm_import_reconstruction.markdown与模块安装sfm_installation.markdown等配套教程本教程示例的完整源码modules/sfm/samples/scene_reconstruction.cpp重建 API 的全部四个重载签名modules/sfm/include/opencv2/sfm/reconstruct.hpp底层实现与 Libmv 参数装配modules/sfm/src/reconstruct.cpp管线配置数据结构BaseSFM、SFMLibmvEuclideanReconstruction、libmv_ReconstructionOptionsmodules/sfm/include/opencv2/sfm/simple_pipeline.hpp模块总览、依赖与安装说明modules/sfm/README.md。赞分享计算机视觉图像处理机器学习【免费下载链接】opencv_contrib项目地址https://gitcode.com/gh_mirrors/ope/opencv_contrib点击查看免费下载相关推荐基于 OpenCV SFM 模块的场景稀疏三维重建实战从图像序列到 libmv 重建管线与 Viz 可视化基于 OpenCV SFM 模块的场景稀疏三维重建实战从图像序列到 libmv 重建管线与 Viz 可视化 导读 本文围绕 opencv_contrib 仓库计算机视觉图像处理深度学习机器学习OpenCV SFM 相机运动估计实战基于轨迹重建 API 的 opencv_contrib 教程解析OpenCV SFM 相机运动估计实战基于轨迹重建 API 的 opencv_contrib 教程解析 导读 本文围绕 opencv_contrib 扩展库中计算机视觉图像处理深度学习机器学习VGGT可视化工具使用详解三维点云与相机轨迹实时展示VGGT可视化工具使用详解三维点云与相机轨迹实时展示 工具概述 VGGTVisual Geometry Grounded Transformer提供了两种人工智能计算机视觉深度学习基础模型上一篇Swagger Codegen 生成的 User 模型详解以 Java Jersey1 Petstore 客户端为例下一篇Linux-NetSpeed性能优化10个技巧让你的网络速度翻倍创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考