openMVG源码学习(四)main_GlobalSFM
之前的链接:
openMVG源码学习(一)main_SfMInit_ImageListing.
openMVG源码学习(二)main_ComputeFeatures
openMVG源码学习(三)main_ComputeMatches.
代码前的准备
删除cmd相关
更改代码书写习惯。。。
前言少序,直接开始。
论文支持
Global Fusion of Relative Motions for Robust, Accurate and Scalable Structure from Motion
输入输出说明
std::string sSfM_Data_Filename{"../img_list_output/sfm_data.json"};
//sfm_data.json路径
std::string sMatchesDir{"../feature_output"},
//几何匹配的路径
sMatchFilename{"matches.f.bin"};
//匹配的文件名
std::string sOutDir{"../sfm_output"};
//输出路径
int iRotationAveragingMethod = int (ROTATION_AVERAGING_L2);
//参数:设置旋转平均法
int iTranslationAveragingMethod = int (TRANSLATION_AVERAGING_SOFTL1);
//参数:设置转换平均法
std::string sIntrinsic_refinement_options = "ADJUST_ALL";
//参数: 内在参数,用于控制哪一个摄像机参数必须被视为保持不变的变量以进行非线性细化的类型
//NONE 固有参数将被视为固定参数
//ADJUST_FOCAL_LENGTH 焦距将被视为细化的变量
//ADJUST_PRINCIPAL_POINT 将主点视为细化变量
//ADJUST_DISTORTION 畸变参数将被视为细化的变量
//ADJUST_ALL 所有参数将被视为细化变量
代码逻辑
参数初始化
iRotationAveragingMethod
if (iRotationAveragingMethod < ROTATION_AVERAGING_L1 ||
iRotationAveragingMethod > ROTATION_AVERAGING_L2 )
//判定iRotationAveragingMethod可用
intrinsic_refinement_options
const cameras::Intrinsic_Parameter_Type intrinsic_refinement_options =
cameras::StringTo_Intrinsic_Parameter_Type(sIntrinsic_refinement_options);
//设置相机内参矩阵参数并判定(判定略)
sfm_data读取
SfM_Data sfm_data;
if (!Load(sfm_data, sSfM_Data_Filename, ESfM_Data(VIEWS|INTRINSICS)))
sImage_describer从图像描述符文件初始化区域类型(用于图像区域提取)
using namespace openMVG::features;
const std::string sImage_describer = stlplus::create_filespec
(sMatchesDir, "image_describer", "json");
std::unique_ptr<Regions> regions_type = Init_region_type_from_file(sImage_describer);
feats_provider特征读取
std::shared_ptr<Features_Provider> feats_provider = std::make_shared<Features_Provider>();
if (!feats_provider->load(sfm_data, sMatchesDir, regions_type))
matches_provider匹配读取
std::shared_ptr<Matches_Provider> matches_provider = std::make_shared<Matches_Provider>();
if (
!(matches_provider->load(sfm_data, sMatchFilename) ||
matches_provider->load(sfm_data, stlplus::create_filespec(sMatchesDir, "matches.e.txt")) ||
matches_provider->load(sfm_data, stlplus::create_filespec(sMatchesDir, "matches.e.bin")))
)
输出文件夹判定
全局SfM重建过程
sfmEngine建立(sfmdata,输出路径,输出路径+Reconstruction_Report.html)
GlobalSfMReconstructionEngine_RelativeMotions sfmEngine(
sfm_data,
sOutDir,
stlplus::create_filespec(sOutDir, "Reconstruction_Report.html"));
配置特征与匹配feats_provider,matches_provider
sfmEngine.SetFeaturesProvider(feats_provider.get());
sfmEngine.SetMatchesProvider(matches_provider.get());
配置重建参数intrinsic_refinement_options
sfmEngine.Set_Intrinsics_Refinement_Type(intrinsic_refinement_options);
配置运动平均方法iRotationAveragingMethod,intrinsic_refinement_options
sfmEngine.SetRotationAveragingMethod(
ERotationAveragingMethod(iRotationAveragingMethod));
sfmEngine.SetTranslationAveragingMethod(
ETranslationAveragingMethod(iTranslationAveragingMethod));
BA开始
if (sfmEngine.Process()) //进行计算的函数
{
std::cout << std::endl << " Total Ac-Global-Sfm took (s): " << timer.elapsed() << std::endl;
//输出报告
std::cout << "...Generating SfM_Report.html" << std::endl;
Generate_SfM_Report(sfmEngine.Get_SfM_Data(),
stlplus::create_filespec(sOutDir, "SfMReconstruction_Report.html"));
//导出计算场景(数据和可视化结果)
std::cout << "...Export SfM_Data to disk." << std::endl;
Save(sfmEngine.Get_SfM_Data(),
stlplus::create_filespec(sOutDir, "sfm_data", ".bin"),
ESfM_Data(ALL));
Save(sfmEngine.Get_SfM_Data(),
stlplus::create_filespec(sOutDir, "cloud_and_poses", ".ply"),
ESfM_Data(ALL));
//ESfM_Data说明
//VIEWS = 1,
//EXTRINSICS = 2,
//INTRINSICS = 4,
//STRUCTURE = 8,
//CONTROL_POINTS = 16,
//ALL = VIEWS | EXTRINSICS | INTRINSICS | STRUCTURE | CONTROL_POINTS
return EXIT_SUCCESS;
}