1 // This file is part of OpenMVG, an Open Multiple View Geometry C++ library.
2
3 // Copyright (c) 2015 Pierre MOULON.
4
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
9 #ifndef OPENMVG_SFM_SFM_DATA_IO_BAF_HPP
10 #define OPENMVG_SFM_SFM_DATA_IO_BAF_HPP
11
12 #include <algorithm>
13 #include <fstream>
14 #include <string>
15 #include <vector>
16
17 #include "openMVG/sfm/sfm_data_io.hpp"
18 #include "third_party/stlplus3/filesystemSimplified/file_system.hpp"
19
20 namespace openMVG {
21 namespace sfm {
22
23 /// Save SfM_Data in an ASCII BAF (Bundle Adjustment File).
24 // --Header
25 // #Intrinsics
26 // #Poses
27 // #Landmarks
28 // --Data
29 // Intrinsic parameters [foc ppx ppy, ...]
30 // Poses [angle axis, camera center]
31 // Landmarks [X Y Z #observations id_intrinsic id_pose x y ...]
32 //--
33 //- Export also a _imgList.txt file with View filename and id_intrinsic & id_pose.
34 // filename id_intrinsic id_pose
35 // The ids allow to establish a link between 3D point observations & the corresponding views
36 //--
37 // Export missing poses as Identity pose to keep tracking of the original id_pose indexes
Save_BAF(const SfM_Data & sfm_data,const std::string & filename,ESfM_Data flags_part)38 inline bool Save_BAF(
39 const SfM_Data & sfm_data,
40 const std::string & filename,
41 ESfM_Data flags_part)
42 {
43 std::ofstream stream(filename);
44 if (!stream)
45 return false;
46
47 bool bOk = false;
48 {
49 stream
50 << sfm_data.GetIntrinsics().size() << '\n'
51 << sfm_data.GetViews().size() << '\n'
52 << sfm_data.GetLandmarks().size() << '\n';
53
54 const Intrinsics & intrinsics = sfm_data.GetIntrinsics();
55 for (const auto & iterIntrinsic : intrinsics )
56 {
57 //get params
58 const std::vector<double> intrinsicsParams = iterIntrinsic.second->getParams();
59 std::copy(intrinsicsParams.begin(), intrinsicsParams.end(),
60 std::ostream_iterator<double>(stream, " "));
61 stream << '\n';
62 }
63
64 const Poses & poses = sfm_data.GetPoses();
65 for ( const auto & iterV : sfm_data.GetViews() )
66 {
67 const View * view = iterV.second.get();
68 if (!sfm_data.IsPoseAndIntrinsicDefined(view))
69 {
70 const Mat3 R = Mat3::Identity();
71 const double * rotation = R.data();
72 std::copy(rotation, rotation+9, std::ostream_iterator<double>(stream, " "));
73 const Vec3 C = Vec3::Zero();
74 const double * center = C.data();
75 std::copy(center, center+3, std::ostream_iterator<double>(stream, " "));
76 stream << '\n';
77 }
78 else
79 {
80 // [Rotation col major 3x3; camera center 3x1]
81 const double * rotation = poses.at(view->id_pose).rotation().data();
82 std::copy(rotation, rotation+9, std::ostream_iterator<double>(stream, " "));
83 const double * center = poses.at(view->id_pose).center().data();
84 std::copy(center, center+3, std::ostream_iterator<double>(stream, " "));
85 stream << '\n';
86 }
87 }
88
89 const Landmarks & landmarks = sfm_data.GetLandmarks();
90 for (const auto & iterLandmarks : landmarks )
91 {
92 // Export visibility information
93 // X Y Z #observations id_cam id_pose x y ...
94 const double * X = iterLandmarks.second.X.data();
95 std::copy(X, X+3, std::ostream_iterator<double>(stream, " "));
96 const Observations & obs = iterLandmarks.second.obs;
97 stream << obs.size() << " ";
98 for ( const auto & iterOb : obs )
99 {
100 const IndexT id_view = iterOb.first;
101 const View * v = sfm_data.GetViews().at(id_view).get();
102 stream
103 << v->id_intrinsic << ' '
104 << v->id_pose << ' '
105 << iterOb.second.x(0) << ' ' << iterOb.second.x(1) << ' ';
106 }
107 stream << '\n';
108 }
109
110 stream.flush();
111 bOk = stream.good();
112 stream.close();
113 }
114
115 // Export View filenames & ids as an imgList.txt file
116 {
117 const std::string sFile = stlplus::create_filespec(
118 stlplus::folder_part(filename), stlplus::basename_part(filename) + std::string("_imgList"), "txt");
119
120 stream.open(sFile);
121 if (!stream)
122 return false;
123 for ( const auto & iterV : sfm_data.GetViews() )
124 {
125 const std::string sView_filename = stlplus::create_filespec(sfm_data.s_root_path,
126 iterV.second->s_Img_path);
127 stream
128 << sView_filename
129 << ' ' << iterV.second->id_intrinsic
130 << ' ' << iterV.second->id_pose << "\n";
131 }
132 stream.flush();
133 bOk = stream.good();
134 stream.close();
135 }
136 return bOk;
137 }
138
139 } // namespace sfm
140 } // namespace openMVG
141
142 #endif // OPENMVG_SFM_SFM_DATA_IO_BAF_HPP
143