1 // This file is part of OpenMVG, an Open Multiple View Geometry C++ library.
2 
3 // Copyright (c) 2012, 2013, 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 #include "openMVG/cameras/Camera_Pinhole.hpp"
10 #include "openMVG/image/image_io.hpp"
11 #include "openMVG/sfm/sfm_data.hpp"
12 #include "openMVG/sfm/sfm_data_io.hpp"
13 #include "openMVG/system/logger.hpp"
14 
15 using namespace openMVG;
16 using namespace openMVG::cameras;
17 using namespace openMVG::geometry;
18 using namespace openMVG::sfm;
19 
20 #include "third_party/cmdLine/cmdLine.h"
21 #include "third_party/stlplus3/filesystemSimplified/file_system.hpp"
22 
23 #include <fstream>
24 
main(int argc,char ** argv)25 int main(int argc, char **argv)
26 {
27   CmdLine cmd;
28 
29   std::string sSfM_Data_Filename;
30   std::string sOutDir = "";
31 
32   cmd.add( make_option('i', sSfM_Data_Filename, "sfmdata") );
33   cmd.add( make_option('o', sOutDir, "outdir") );
34 
35   try {
36     if (argc == 1) throw std::string("Invalid command line parameter.");
37     cmd.process(argc, argv);
38   } catch (const std::string& s) {
39     OPENMVG_LOG_INFO << "Usage: " << argv[0] << '\n'
40       << "[-i|--sfmdata] filename, the SfM_Data file to convert\n"
41       << "[-o|--outdir] path.";
42 
43     OPENMVG_LOG_ERROR << s;
44     return EXIT_FAILURE;
45   }
46 
47   OPENMVG_LOG_INFO << " You called : " << argv[0]
48     << "\n--sfmdata " << sSfM_Data_Filename
49     << "\n--outdir " << sOutDir;
50 
51   bool bOneHaveDisto = false;
52 
53   // Create output dir
54   if (!stlplus::folder_exists(sOutDir))
55     stlplus::folder_create( sOutDir );
56 
57   // Read the SfM scene
58   SfM_Data sfm_data;
59   if (!Load(sfm_data, sSfM_Data_Filename, ESfM_Data(VIEWS|INTRINSICS|EXTRINSICS))) {
60     OPENMVG_LOG_ERROR << "The input SfM_Data file \""<< sSfM_Data_Filename << "\" cannot be read.";
61     return EXIT_FAILURE;
62   }
63 
64   for (Views::const_iterator iter = sfm_data.GetViews().begin();
65       iter != sfm_data.GetViews().end(); ++iter)
66   {
67     const View * view = iter->second.get();
68     if (!sfm_data.IsPoseAndIntrinsicDefined(view))
69         continue;
70 
71     // Valid view, we can ask a pose & intrinsic data
72     const Pose3 pose = sfm_data.GetPoseOrDie(view);
73     Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic);
74     const IntrinsicBase * cam = iterIntrinsic->second.get();
75 
76     if (!cameras::isPinhole(cam->getType()))
77         continue;
78     const Pinhole_Intrinsic * pinhole_cam = static_cast<const Pinhole_Intrinsic *>(cam);
79 
80     // Extrinsic
81     const Vec3 t = pose.translation();
82     const Mat3 R = pose.rotation();
83     // Intrinsic
84     const double f = pinhole_cam->focal();
85     const Vec2 pp = pinhole_cam->principal_point();
86 
87     // Image size in px
88     const int w = pinhole_cam->w();
89     const int h = pinhole_cam->h();
90 
91     // We can now create the .cam file for the View in the output dir
92     std::ofstream outfile( stlplus::create_filespec(
93                 sOutDir, stlplus::basename_part(view->s_Img_path), "cam" ).c_str() );
94     // See https://github.com/nmoehrle/mvs-texturing/blob/master/apps/texrecon/arguments.cpp
95     // for full specs
96     const int largerDim = w > h ? w : h;
97     outfile << t(0) << " " << t(1) << " " << t(2) << " "
98         << R(0,0) << " " << R(0,1) << " " << R(0,2) << " "
99         << R(1,0) << " " << R(1,1) << " " << R(1,2) << " "
100         << R(2,0) << " " << R(2,1) << " " << R(2,2) << "\n"
101         << f / largerDim << " 0 0 1 " << pp(0) / w << " " << pp(1) / h;
102     outfile.close();
103 
104     if (cam->have_disto())
105       bOneHaveDisto = true;
106   }
107 
108   const std::string sUndistMsg = bOneHaveDisto ? "undistorded" : "";
109   const std::string sQuitMsg = std::string("Your SfM_Data file was succesfully converted!\n") +
110     "Now you can copy your " + sUndistMsg + " images in the \"" + sOutDir + "\" directory and run MVS Texturing";
111   OPENMVG_LOG_INFO << sQuitMsg;
112   return EXIT_SUCCESS;
113 }
114