ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
PinholeCameraTrajectoryIO.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "PinholeCameraTrajectoryIO.h"
9 
10 #include <FileSystem.h>
11 #include <IJsonConvertibleIO.h>
12 #include <Logging.h>
13 
14 #include <Eigen/Dense>
15 #include <Eigen/Geometry>
16 #include <unordered_map>
17 
18 namespace cloudViewer {
19 namespace io {
20 
22  const std::string &filename,
23  camera::PinholeCameraTrajectory &trajectory) {
24  return ReadIJsonConvertible(filename, trajectory);
25 }
26 
28  const std::string &filename,
29  const camera::PinholeCameraTrajectory &trajectory) {
30  return WriteIJsonConvertibleToJSON(filename, trajectory);
31 }
32 
33 static const std::unordered_map<
34  std::string,
35  std::function<bool(const std::string &,
41  };
42 
43 static const std::unordered_map<
44  std::string,
45  std::function<bool(const std::string &,
51  };
52 
53 using namespace cloudViewer;
54 std::shared_ptr<camera::PinholeCameraTrajectory>
56  auto trajectory = std::make_shared<camera::PinholeCameraTrajectory>();
58  return trajectory;
59 }
60 
61 bool ReadPinholeCameraTrajectory(const std::string &filename,
62  camera::PinholeCameraTrajectory &trajectory) {
63  std::string filename_ext =
65  if (filename_ext.empty()) {
67  "Read camera::PinholeCameraTrajectory failed: unknown file "
68  "extension.");
69  return false;
70  }
71  auto map_itr =
73  if (map_itr == file_extension_to_trajectory_read_function.end()) {
75  "Read camera::PinholeCameraTrajectory failed: unknown file "
76  "extension.");
77  return false;
78  }
79  return map_itr->second(filename, trajectory);
80 }
81 
83  const std::string &filename,
84  const camera::PinholeCameraTrajectory &trajectory) {
85  std::string filename_ext =
87  if (filename_ext.empty()) {
89  "Write camera::PinholeCameraTrajectory failed: unknown file "
90  "extension.");
91  return false;
92  }
93  auto map_itr =
95  if (map_itr == file_extension_to_trajectory_write_function.end()) {
97  "Write camera::PinholeCameraTrajectory failed: unknown file "
98  "extension.");
99  return false;
100  }
101  return map_itr->second(filename, trajectory);
102 }
103 
105  const std::string &filename,
106  camera::PinholeCameraTrajectory &trajectory) {
108  if (trajectory.parameters_.size() >= 1 &&
109  trajectory.parameters_[0].intrinsic_.IsValid()) {
110  intrinsic = trajectory.parameters_[0].intrinsic_;
111  } else {
112  intrinsic = camera::PinholeCameraIntrinsic(
114  }
115  trajectory.parameters_.clear();
116  FILE *f = utility::filesystem::FOpen(filename, "r");
117  if (f == NULL) {
118  utility::LogWarning("Read TUM failed: unable to open file: {}",
119  filename);
120  return false;
121  }
122  char line_buffer[DEFAULT_IO_BUFFER_SIZE];
123  double ts, x, y, z, qx, qy, qz, qw;
124  Eigen::Matrix4d transform;
125  while (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f)) {
126  if (strlen(line_buffer) > 0 && line_buffer[0] != '#') {
127  if (sscanf(line_buffer, "%lf %lf %lf %lf %lf %lf %lf %lf", &ts, &x,
128  &y, &z, &qx, &qy, &qz, &qw) != 8) {
129  utility::LogWarning("Read TUM failed: unrecognized format.");
130  fclose(f);
131  return false;
132  }
133 
134  transform.setIdentity();
135  transform.topLeftCorner<3, 3>() =
136  Eigen::Quaterniond(qw, qx, qy, qz).toRotationMatrix();
137  transform.topRightCorner<3, 1>() = Eigen::Vector3d(x, y, z);
138  auto param = camera::PinholeCameraParameters();
139  param.intrinsic_ = intrinsic;
140  param.extrinsic_ = transform.inverse();
141  trajectory.parameters_.push_back(param);
142  }
143  }
144  fclose(f);
145  return true;
146 }
147 
149  const std::string &filename,
150  const camera::PinholeCameraTrajectory &trajectory) {
151  FILE *f = utility::filesystem::FOpen(filename, "w");
152  if (f == NULL) {
153  utility::LogWarning("Write TUM failed: unable to open file: {}",
154  filename);
155  return false;
156  }
157 
158  Eigen::Quaterniond q;
159  fprintf(f, "# TUM trajectory, format: <t> <x> <y> <z> <qx> <qy> <qz> <qw>");
160  for (size_t i = 0; i < trajectory.parameters_.size(); i++) {
161  const Eigen::Matrix4d transform =
162  trajectory.parameters_[i].extrinsic_.inverse();
163  q = transform.topLeftCorner<3, 3>();
164  fprintf(f, "%zu %lf %lf %lf %lf %lf %lf %lf\n", i, transform(0, 3),
165  transform(1, 3), transform(2, 3), q.x(), q.y(), q.z(), q.w());
166  }
167  fclose(f);
168  return true;
169 }
170 
172  const std::string &filename,
173  camera::PinholeCameraTrajectory &trajectory) {
175  if (trajectory.parameters_.size() >= 1 &&
176  trajectory.parameters_[0].intrinsic_.IsValid()) {
177  intrinsic = trajectory.parameters_[0].intrinsic_;
178  } else {
179  intrinsic = camera::PinholeCameraIntrinsic(
181  }
182  trajectory.parameters_.clear();
183  FILE *f = utility::filesystem::FOpen(filename, "r");
184  if (f == NULL) {
185  utility::LogWarning("Read LOG failed: unable to open file: {}",
186  filename.c_str());
187  return false;
188  }
189  char line_buffer[DEFAULT_IO_BUFFER_SIZE];
190  int i, j, k;
191  int res;
192  Eigen::Matrix4d trans;
193  while (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f)) {
194  if (strlen(line_buffer) > 0 && line_buffer[0] != '#') {
195  if (sscanf(line_buffer, "%d %d %d", &i, &j, &k) != 3) {
196  utility::LogWarning("Read LOG failed: unrecognized format.");
197  fclose(f);
198  return false;
199  }
200  if (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f) == 0) {
201  utility::LogWarning("Read LOG failed: unrecognized format.");
202  fclose(f);
203  return false;
204  } else {
205  res = sscanf(line_buffer, "%lf %lf %lf %lf", &trans(0, 0),
206  &trans(0, 1), &trans(0, 2), &trans(0, 3));
207  }
208  if (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f) == 0) {
209  utility::LogWarning("Read LOG failed: unrecognized format.");
210  fclose(f);
211  return false;
212  } else {
213  res = sscanf(line_buffer, "%lf %lf %lf %lf", &trans(1, 0),
214  &trans(1, 1), &trans(1, 2), &trans(1, 3));
215  }
216  if (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f) == 0) {
217  utility::LogWarning("Read LOG failed: unrecognized format.");
218  fclose(f);
219  return false;
220  } else {
221  res = sscanf(line_buffer, "%lf %lf %lf %lf", &trans(2, 0),
222  &trans(2, 1), &trans(2, 2), &trans(2, 3));
223  }
224  if (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f) == 0) {
225  utility::LogWarning("Read LOG failed: unrecognized format.");
226  fclose(f);
227  return false;
228  } else {
229  res = sscanf(line_buffer, "%lf %lf %lf %lf", &trans(3, 0),
230  &trans(3, 1), &trans(3, 2), &trans(3, 3));
231  }
232  auto param = camera::PinholeCameraParameters();
233  param.intrinsic_ = intrinsic;
234  param.extrinsic_ = trans.inverse();
235  trajectory.parameters_.push_back(param);
236  }
237  }
238  fclose(f);
239  return true;
240 }
241 
243  const std::string &filename,
244  const camera::PinholeCameraTrajectory &trajectory) {
245  FILE *f = utility::filesystem::FOpen(filename.c_str(), "w");
246  if (f == NULL) {
247  utility::LogWarning("Write LOG failed: unable to open file: {}",
248  filename);
249  return false;
250  }
251  for (size_t i = 0; i < trajectory.parameters_.size(); i++) {
252  Eigen::Matrix4d_u trans =
253  trajectory.parameters_[i].extrinsic_.inverse();
254  fprintf(f, "%d %d %d\n", (int)i, (int)i, (int)i + 1);
255  fprintf(f, "%.8f %.8f %.8f %.8f\n", trans(0, 0), trans(0, 1),
256  trans(0, 2), trans(0, 3));
257  fprintf(f, "%.8f %.8f %.8f %.8f\n", trans(1, 0), trans(1, 1),
258  trans(1, 2), trans(1, 3));
259  fprintf(f, "%.8f %.8f %.8f %.8f\n", trans(2, 0), trans(2, 1),
260  trans(2, 2), trans(2, 3));
261  fprintf(f, "%.8f %.8f %.8f %.8f\n", trans(3, 0), trans(3, 1),
262  trans(3, 2), trans(3, 3));
263  }
264  fclose(f);
265  return true;
266 }
267 
268 } // namespace io
269 } // namespace cloudViewer
std::string filename
#define NULL
Contains the pinhole camera intrinsic parameters.
Contains both intrinsic and extrinsic pinhole camera parameters.
std::vector< PinholeCameraParameters > parameters_
List of PinholeCameraParameters objects.
#define LogWarning(...)
Definition: Logging.h:72
#define DEFAULT_IO_BUFFER_SIZE
Definition: Logging.h:31
normal_z y
normal_z x
normal_z z
Eigen::Matrix< double, 4, 4, Eigen::DontAlign > Matrix4d_u
Definition: Eigen.h:113
@ PrimeSenseDefault
Default settings for PrimeSense camera sensor.
bool ReadPinholeCameraTrajectoryFromLOG(const std::string &filename, camera::PinholeCameraTrajectory &trajectory)
bool WritePinholeCameraTrajectoryToTUM(const std::string &filename, const camera::PinholeCameraTrajectory &trajectory)
bool ReadPinholeCameraTrajectoryFromJSON(const std::string &filename, camera::PinholeCameraTrajectory &trajectory)
bool ReadPinholeCameraTrajectory(const std::string &filename, camera::PinholeCameraTrajectory &trajectory)
bool ReadPinholeCameraTrajectoryFromTUM(const std::string &filename, camera::PinholeCameraTrajectory &trajectory)
bool WritePinholeCameraTrajectory(const std::string &filename, const camera::PinholeCameraTrajectory &trajectory)
bool WritePinholeCameraTrajectoryToLOG(const std::string &filename, const camera::PinholeCameraTrajectory &trajectory)
static const std::unordered_map< std::string, std::function< bool(const std::string &, const camera::PinholeCameraTrajectory &)> > file_extension_to_trajectory_write_function
bool WriteIJsonConvertibleToJSON(const std::string &filename, const cloudViewer::utility::IJsonConvertible &object)
bool WritePinholeCameraTrajectoryToJSON(const std::string &filename, const camera::PinholeCameraTrajectory &trajectory)
std::shared_ptr< camera::PinholeCameraTrajectory > CreatePinholeCameraTrajectoryFromFile(const std::string &filename)
static const std::unordered_map< std::string, std::function< bool(const std::string &, camera::PinholeCameraTrajectory &)> > file_extension_to_trajectory_read_function
bool ReadIJsonConvertible(const std::string &filename, cloudViewer::utility::IJsonConvertible &object)
std::string GetFileExtensionInLowerCase(const std::string &filename)
Definition: FileSystem.cpp:281
FILE * FOpen(const std::string &filename, const std::string &mode)
Definition: FileSystem.cpp:609
Generic file read and write utility for python interface.