MVE - Multi-View Environment mve-devel
Loading...
Searching...
No Matches
bundle_io.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015, Simon Fuhrmann
3 * TU Darmstadt - Graphics, Capture and Massively Parallel Computing
4 * All rights reserved.
5 *
6 * This software may be modified and distributed under the terms
7 * of the BSD 3-Clause license. See the LICENSE.txt file for details.
8 */
9
10#include <cerrno>
11#include <cstring>
12#include <iostream>
13#include <string>
14#include <fstream>
15#include <map>
16#include <cassert>
17
18#include "util/system.h"
19#include "util/file_system.h"
20#include "util/strings.h"
21#include "util/exception.h"
22#include "math/matrix.h"
23#include "math/vector.h"
24#include "mve/bundle_io.h"
25#include "mve/image_tools.h"
26#include "mve/depthmap.h"
27
28
30
31/* ------------------- MVE native bundle format ------------------- */
32
33Bundle::Ptr
34load_mve_bundle (std::string const& filename)
35{
36 return load_photosynther_bundle(filename);
37}
38
39void
40save_mve_bundle (Bundle::ConstPtr bundle, std::string const& filename)
41{
42 save_photosynther_bundle(bundle, filename);
43}
44
45/* -------------- Support for NVM files (VisualSFM) --------------- */
46
47namespace
48{
49 /* Conversion from quaternion to rotation matrix. */
51 get_rot_from_quaternion(double const* values)
52 {
53 math::Vec4f q(values);
54 q.normalize();
55
57 rot[0] = 1.0f - 2.0f * q[2] * q[2] - 2.0f * q[3] * q[3];
58 rot[1] = 2.0f * q[1] * q[2] - 2.0f * q[3] * q[0];
59 rot[2] = 2.0f * q[1] * q[3] + 2.0f * q[2] * q[0];
60
61 rot[3] = 2.0f * q[1] * q[2] + 2.0f * q[3] * q[0];
62 rot[4] = 1.0f - 2.0f * q[1] * q[1] - 2.0f * q[3] * q[3];
63 rot[5] = 2.0f * q[2] * q[3] - 2.0f * q[1] * q[0];
64
65 rot[6] = 2.0f * q[1] * q[3] - 2.0f * q[2] * q[0];
66 rot[7] = 2.0f * q[2] * q[3] + 2.0f * q[1] * q[0];
67 rot[8] = 1.0f - 2.0f * q[1] * q[1] - 2.0f * q[2] * q[2];
68 return rot;
69 }
70} // namespace
71
72Bundle::Ptr
73load_nvm_bundle (std::string const& filename,
74 std::vector<AdditionalCameraInfo>* camera_info)
75{
76 std::ifstream in(filename.c_str());
77 if (!in.good())
78 throw util::FileException(filename, std::strerror(errno));
79
80 /* Check NVM file signature. */
81 std::cout << "NVM: Loading file..." << std::endl;
82 std::string signature;
83 in >> signature;
84 if (signature != "NVM_V3")
85 throw util::Exception("Invalid NVM signature");
86
87 /* Discard the rest of the line (e.g. fixed camera parameter info). */
88 {
89 std::string temp;
90 std::getline(in, temp);
91 }
92
93 // TODO: Handle multiple models.
94
95 /* Read number of views. */
96 int num_views = 0;
97 in >> num_views;
98 if (num_views < 0 || num_views > 10000)
99 throw util::Exception("Invalid number of views: ",
100 util::string::get(num_views));
101
102 /* Create new bundle and prepare NVM specific output. */
103 Bundle::Ptr bundle = Bundle::create();
104 Bundle::Cameras& bundle_cams = bundle->get_cameras();
105 bundle_cams.reserve(num_views);
106 std::vector<AdditionalCameraInfo> nvm_cams;
107 nvm_cams.reserve(num_views);
108
109 /* Read views. */
110 std::cout << "NVM: Number of views: " << num_views << std::endl;
111 std::string nvm_path = util::fs::dirname(filename);
112 for (int i = 0; i < num_views; ++i)
113 {
114 AdditionalCameraInfo nvm_cam;
115 CameraInfo bundle_cam;
116
117 /* Filename and focal length. */
118 in >> nvm_cam.filename;
119 in >> bundle_cam.flen;
120
121 /* Camera rotation and center. */
122 double quat[4];
123 for (int j = 0; j < 4; ++j)
124 in >> quat[j];
125 math::Matrix3f rot = get_rot_from_quaternion(quat);
126 math::Vec3f center, trans;
127 for (int j = 0; j < 3; ++j)
128 in >> center[j];
129 trans = rot * -center;
130 std::copy(rot.begin(), rot.end(), bundle_cam.rot);
131 std::copy(trans.begin(), trans.end(), bundle_cam.trans);
132
133 /* Radial distortion. */
134 in >> nvm_cam.radial_distortion;
135 bundle_cam.dist[0] = nvm_cam.radial_distortion;
136 bundle_cam.dist[1] = 0.0f;
137
138 /* If the filename is not absolute, make relative to NVM. */
139 if (!util::fs::is_absolute(nvm_cam.filename))
140 nvm_cam.filename = util::fs::join_path(nvm_path, nvm_cam.filename);
141
142 /* Jettison trailing zero. */
143 int temp;
144 in >> temp;
145
146 if (in.eof())
147 throw util::Exception("Unexpected EOF in NVM file");
148
149 bundle_cams.push_back(bundle_cam);
150 nvm_cams.push_back(nvm_cam);
151 }
152
153 /* Read number of features. */
154 int num_features = 0;
155 in >> num_features;
156 if (num_features < 0 || num_features > 1000000000)
157 throw util::Exception("Invalid number of features: ",
158 util::string::get(num_features));
159
160 Bundle::Features& features = bundle->get_features();
161 features.reserve(num_features);
162
163 /* Read points. */
164 std::cout << "NVM: Number of features: " << num_features << std::endl;
165 std::size_t num_strange_points = 0;
166 for (int i = 0; i < num_features; ++i)
167 {
168 Bundle::Feature3D feature;
169 for (int j = 0; j < 3; ++j)
170 in >> feature.pos[j];
171 for (int j = 0; j < 3; ++j)
172 {
173 in >> feature.color[j];
174 feature.color[j] /= 255.0f;
175 }
176
177 /* Read number of refs. */
178 int num_refs = 0;
179 in >> num_refs;
180
181 /* Detect strange points not seen by cameras. Why does this happen? */
182 if (num_refs == 0)
183 {
184 num_strange_points += 1;
185 continue;
186 }
187
188 /* There should be at least 2 cameras that see the point. */
189 if (num_refs < 2 || num_refs > num_views)
190 throw util::Exception("Invalid number of feature refs: ",
191 util::string::get(num_refs));
192
193 /* Read refs. */
194 feature.refs.reserve(num_refs);
195 for (int j = 0; j < num_refs; ++j)
196 {
198 in >> ref.view_id >> ref.feature_id >> ref.pos[0] >> ref.pos[1];
199 feature.refs.push_back(ref);
200 }
201 features.push_back(feature);
202 }
203 in.close();
204
205 /* Warn about strange points. */
206 if (num_strange_points > 0)
207 {
208 std::cout << "NVM: " << num_strange_points
209 << " strange points not seem by any camera!" << std::endl;
210 }
211
212 if (camera_info != nullptr)
213 std::swap(*camera_info, nvm_cams);
214
215 return bundle;
216}
217
218/* ----------- Common code for Bundler and Photosynther ----------- */
219
220/*
221 * Both Bundler and Photosynther formats are quite similar so one parser
222 * can do all the work with minor differences given the format. The format
223 * could easily be detected automatically but this is avoided here.
224 *
225 * Photosynther bundle file format
226 * -------------------------------
227 *
228 * "drews 1.0"
229 * <num_cameras> <num_features>
230 * <cam 1 line 1> // Focal length, Radial distortion: f rd1 rd2
231 * <cam 1 line 2> // Rotation matrix row 1: r11 r12 r13
232 * <cam 1 line 3> // Rotation matrix row 2: r21 r22 r23
233 * <cam 1 line 4> // Rotation matrix row 3: r31 r32 r33
234 * <cam 1 line 5> // Translation vector: t1 t2 t3
235 * ...
236 * <point 1 position> // x y z (floats)
237 * <point 1 color> // r g b (uchars)
238 * <point 1 visibility> // <list length (uint)> ( <img id (uint)> <sift id (uint)> <reproj. quality (float)> ) ...
239 * ...
240 *
241 * Noah Snavely bundle file format
242 * -------------------------------
243 *
244 * "# Bundle file v0.3"
245 * <num_cameras> <num_features>
246 * <cam 1 line 1> // Focal length, Radial distortion: f k1 k2
247 * <cam 1 line 2> // Rotation matrix row 1: r11 r12 r13
248 * <cam 1 line 3> // Rotation matrix row 2: r21 r22 r23
249 * <cam 1 line 4> // Rotation matrix row 3: r31 r32 r33
250 * <cam 1 line 5> // Translation vector: t1 t2 t3
251 * ...
252 * <point 1 position> // x y z (floats)
253 * <point 1 color> // r g b (uchars)
254 * <point 1 visibility> // <list length (uint)> ( <img ID (uint)> <sift ID (uint)> <x (float)> <y (float)> ) ...
255 * ...
256 *
257 * A few notes on the bundler format: Each camera in the bundle file
258 * corresponds to the ordered list of input images. Some cameras are set
259 * to zero, which means the input image was not registered. <cam ID> is
260 * the ID w.r.t. the input images, <sift ID> is the ID of the SIFT feature
261 * point for that image. In the Noah bundler, <x> and <y> are floating point
262 * positions of the keypoint in the in the image-centered coordinate system.
263 */
264
265namespace
266{
267 enum BundleFormat
268 {
269 BUNDLE_FORMAT_PHOTOSYNTHER,
270 BUNDLE_FORMAT_NOAHBUNDLER,
271 BUNDLE_FORMAT_ERROR
272 };
273} // namespace
274
275Bundle::Ptr
276load_bundler_ps_intern (std::string const& filename, BundleFormat format)
277{
278 std::ifstream in(filename.c_str());
279 if (!in.good())
280 throw util::FileException(filename, std::strerror(errno));
281
282 /* Read version information in the first line. */
283 std::string version_string;
284 std::getline(in, version_string);
285 util::string::clip_newlines(&version_string);
286 util::string::clip_whitespaces(&version_string);
287
288 std::string parser_string;
289 if (format == BUNDLE_FORMAT_PHOTOSYNTHER)
290 {
291 parser_string = "Photosynther";
292 if (version_string != "drews 1.0")
293 format = BUNDLE_FORMAT_ERROR;
294 }
295 else if (format == BUNDLE_FORMAT_NOAHBUNDLER)
296 {
297 parser_string = "Bundler";
298 if (version_string != "# Bundle file v0.3")
299 format = BUNDLE_FORMAT_ERROR;
300 }
301 else
302 throw util::Exception("Invalid parser format");
303
304 if (format == BUNDLE_FORMAT_ERROR)
305 throw util::Exception("Invalid file signature: ", version_string);
306
307 /* Read number of cameras and number of points. */
308 int num_views = 0;
309 int num_features = 0;
310 in >> num_views >> num_features;
311
312 if (in.eof())
313 throw util::Exception("Unexpected EOF in bundle file");
314
315 if (num_views < 0 || num_views > 10000
316 || num_features < 0 || num_features > 100000000)
317 throw util::Exception("Spurious amount of cameras or features");
318
319 /* Print message according to detected parser format. */
320 std::cout << "Reading " << parser_string << " file ("
321 << num_views << " cameras, "
322 << num_features << " features)..." << std::endl;
323
324 Bundle::Ptr bundle = Bundle::create();
325
326 /* Read all cameras. */
327 Bundle::Cameras& cameras = bundle->get_cameras();
328 cameras.reserve(num_views);
329 for (int i = 0; i < num_views; ++i)
330 {
331 cameras.push_back(CameraInfo());
332 CameraInfo& cam = cameras.back();
333 in >> cam.flen >> cam.dist[0] >> cam.dist[1];
334 for (int j = 0; j < 9; ++j)
335 in >> cam.rot[j];
336 for (int j = 0; j < 3; ++j)
337 in >> cam.trans[j];
338 }
339
340 if (in.eof())
341 throw util::Exception("Unexpected EOF in bundle file");
342 if (in.fail())
343 throw util::Exception("Bundle file read error");
344
345 /* Read all features. */
346 Bundle::Features& features = bundle->get_features();
347 features.reserve(num_features);
348 for (int i = 0; i < num_features; ++i)
349 {
350 /* Insert the new (uninitialized) point. */
351 features.push_back(Bundle::Feature3D());
352 Bundle::Feature3D& feature = features.back();
353
354 /* Read point position and color. */
355 for (int j = 0; j < 3; ++j)
356 in >> feature.pos[j];
357 for (int j = 0; j < 3; ++j)
358 {
359 in >> feature.color[j];
360 feature.color[j] /= 255.0f;
361 }
362
363 /* Read feature references. */
364 int ref_amount = 0;
365 in >> ref_amount;
366 if (ref_amount < 0 || ref_amount > num_views)
367 {
368 in.close();
369 throw util::Exception("Invalid feature reference amount");
370 }
371
372 for (int j = 0; j < ref_amount; ++j)
373 {
374 /*
375 * Photosynther: The third parameter is the reprojection quality.
376 * Bundler: The third and forth parameter are the floating point
377 * x- and y-coordinate in an image-centered coordinate system.
378 */
380 float dummy_float;
381 if (format == BUNDLE_FORMAT_PHOTOSYNTHER)
382 {
383 in >> ref.view_id >> ref.feature_id;
384 in >> dummy_float; // Drop reprojection quality.
385 std::fill(ref.pos, ref.pos + 2, -1.0f);
386 }
387 else if (format == BUNDLE_FORMAT_NOAHBUNDLER)
388 {
389 in >> ref.view_id >> ref.feature_id;
390 in >> ref.pos[0] >> ref.pos[1];
391 }
392 feature.refs.push_back(ref);
393 }
394
395 /* Check for premature EOF. */
396 if (in.eof())
397 {
398 std::cerr << "Warning: Unexpected EOF (at feature "
399 << i << ")" << std::endl;
400 features.pop_back();
401 break;
402 }
403 }
404
405 in.close();
406 return bundle;
407}
408
409/* ------------------ Support for Noah "Bundler" ----------------- */
410
411Bundle::Ptr
412load_bundler_bundle (std::string const& filename)
413{
414 return load_bundler_ps_intern(filename, BUNDLE_FORMAT_NOAHBUNDLER);
415}
416
417/* ------------------- Support for Photosynther ------------------- */
418
419Bundle::Ptr
420load_photosynther_bundle (std::string const& filename)
421{
422 return load_bundler_ps_intern(filename, BUNDLE_FORMAT_PHOTOSYNTHER);
423}
424
425void
426save_photosynther_bundle (Bundle::ConstPtr bundle, std::string const& filename)
427{
428 Bundle::Features const& features = bundle->get_features();
429 Bundle::Cameras const& cameras = bundle->get_cameras();
430
431 std::cout << "Writing bundle (" << cameras.size() << " cameras, "
432 << features.size() << " features): " << filename << "...\n";
433
434 std::ofstream out(filename.c_str(), std::ios::binary);
435 if (!out.good())
436 throw util::FileException(filename, std::strerror(errno));
437
438 out << "drews 1.0\n";
439 out << cameras.size() << " " << features.size() << "\n";
440
441 /* Write all cameras to bundle file. */
442 for (std::size_t i = 0; i < cameras.size(); ++i)
443 {
444 CameraInfo const& cam = cameras[i];
445
446 bool camera_valid = true;
447 for (int j = 0; camera_valid && j < 3; ++j)
448 if (MATH_ISINF(cam.trans[j]) || MATH_ISNAN(cam.trans[j]))
449 camera_valid = false;
450 for (int j = 0; camera_valid && j < 9; ++j)
451 if (MATH_ISINF(cam.rot[j]) || MATH_ISNAN(cam.rot[j]))
452 camera_valid = false;
453
454 if (cam.flen == 0.0f || !camera_valid)
455 {
456 for (int i = 0; i < 5 * 3; ++i)
457 out << "0" << (i % 3 == 2 ? "\n" : " ");
458 continue;
459 }
460
461 out << cam.flen << " " << cam.dist[0] << " " << cam.dist[1] << "\n";
462 out << cam.rot[0] << " " << cam.rot[1] << " " << cam.rot[2] << "\n";
463 out << cam.rot[3] << " " << cam.rot[4] << " " << cam.rot[5] << "\n";
464 out << cam.rot[6] << " " << cam.rot[7] << " " << cam.rot[8] << "\n";
465 out << cam.trans[0] << " " << cam.trans[1]
466 << " " << cam.trans[2] << "\n";
467 }
468
469 /* Write all features to bundle file. */
470 for (std::size_t i = 0; i < features.size(); ++i)
471 {
472 Bundle::Feature3D const& p = features[i];
473 out << p.pos[0] << " " << p.pos[1] << " " << p.pos[2] << "\n";
474 out << static_cast<int>(p.color[0] * 255.0f + 0.5f) << " "
475 << static_cast<int>(p.color[1] * 255.0f + 0.5f) << " "
476 << static_cast<int>(p.color[2] * 255.0f + 0.5f) << "\n";
477 out << p.refs.size();
478 for (std::size_t j = 0; j < p.refs.size(); ++j)
479 {
480 Bundle::Feature2D const& ref = p.refs[j];
481 out << " " << ref.view_id << " " << ref.feature_id << " 0";
482 }
483 out << "\n";
484 }
485
486 out.close();
487}
488
489/* -------------- Support for Colmap --------------- */
490
491// See colmap/src/util/types.h
492typedef uint32_t camera_t;
493typedef uint32_t image_t;
494typedef uint64_t image_pair_t;
495typedef uint32_t point2D_t;
496typedef uint64_t point3D_t;
497
498std::map<camera_t,std::string> camera_model_code_to_name;
499
500void
502 camera_model_code_to_name.emplace(0, "SIMPLE_PINHOLE");
503 camera_model_code_to_name.emplace(1, "PINHOLE");
504 camera_model_code_to_name.emplace(2, "SIMPLE_RADIAL");
505 camera_model_code_to_name.emplace(3, "RADIAL");
506 camera_model_code_to_name.emplace(4, "OPENCV");
507 camera_model_code_to_name.emplace(5, "OPENCV_FISHEYE");
508 camera_model_code_to_name.emplace(6, "FULL_OPENCV");
509 camera_model_code_to_name.emplace(7, "FOV");
510 camera_model_code_to_name.emplace(8, "SIMPLE_RADIAL_FISHEYE");
511 camera_model_code_to_name.emplace(9, "RADIAL_FISHEYE");
512 camera_model_code_to_name.emplace(10, "THIN_PRISM_FISHEYE");
513}
514
515void
516check_stream(std::ifstream & in, std::string const& filename)
517{
518 if (!in.good())
519 throw util::FileException(filename, std::strerror(errno));
520}
521
522void
523consume_comment_lines(std::ifstream & in)
524{
525 while (in.peek() == '#')
526 {
527 std::string temp;
528 std::getline(in, temp);
529 }
530}
531
532void
534 std::string const& model,
535 std::vector<float> const& params,
536 uint32_t width,
537 uint32_t height)
538{
539 // https://github.com/colmap/colmap/blob/dev/src/base/camera_models.h
540 // https://github.com/simonfuhrmann/mve/blob/master/libs/mve/camera.cc
541 if (model == "SIMPLE_PINHOLE")
542 {
543 // Simple pinhole: f, cx, cy
544 camera_info.flen = params[0];
545 camera_info.ppoint[0] = params[1] / width;
546 camera_info.ppoint[1] = params[2] / height;
547 }
548 else if (model == "PINHOLE")
549 {
550 // Pinhole: fx, fy, cx, cy
551 float fx = params[0];
552 float fy = params[1];
553 float dim_aspect = static_cast<float>(width) / height;
554 float pixel_aspect = fy / fx;
555 float img_aspect = dim_aspect * pixel_aspect;
556 if (img_aspect < 1.0f) {
557 camera_info.flen = fy / height;
558 } else {
559 camera_info.flen = fx / width;
560 }
561 camera_info.paspect = pixel_aspect;
562 camera_info.ppoint[0] = params[2] / width;
563 camera_info.ppoint[1] = params[3] / height;
564 }
565 else
566 {
567 std::string msg = "Unsupported camera model with radial distortion "
568 "detected! If possible, re-run the SfM reconstruction with the "
569 "SIMPLE_PINHOLE or the PINHOLE camera model (recommended). "
570 "Otherwise, use the undistortion step in Colmap to obtain "
571 "undistorted images and corresponding camera models without radial "
572 "distortion.";
573 throw util::Exception(msg.c_str());
574 }
575}
576
577void
578load_colmap_cameras_txt(std::string const& cameras_filename,
579 std::map<uint32_t, CameraInfo>& camera_colmap_id_to_info)
580{
581 std::cout << "Colmap: Loading camera.txt file..." << std::endl;
582 std::ifstream in_cameras(cameras_filename.c_str());
583 check_stream(in_cameras, cameras_filename);
584 consume_comment_lines(in_cameras);
585 std::string camera_line;
586 uint32_t camera_colmap_id; // starts at 1
587 std::string model_name;
588 uint32_t width, height;
589 std::vector<float> params;
590 while(getline(in_cameras, camera_line))
591 {
592 std::stringstream camera_line_ss(camera_line);
593 camera_line_ss >> camera_colmap_id >> model_name >> width >> height;
594 if (camera_line_ss.eof())
595 throw util::Exception("Missing parameters");
596 params.clear();
597 float param;
598 while (camera_line_ss >> param)
599 params.push_back(param);
600 CameraInfo camera_info;
602 camera_info, model_name, params, width, height);
603 camera_colmap_id_to_info[camera_colmap_id] = camera_info;
604 }
605 in_cameras.close();
606}
607
608void
610 math::Vec4d& quat,
611 math::Vec3d& trans,
612 CameraInfo* bundle_cam)
613{
614 bundle_cam->flen = model.flen;
615 bundle_cam->paspect = model.paspect;
616 bundle_cam->ppoint[0] = model.ppoint[0];
617 bundle_cam->ppoint[1] = model.ppoint[1];
618 bundle_cam->dist[0] = model.dist[0];
619 bundle_cam->dist[1] = model.dist[1];
620 math::Matrix3f rot = get_rot_from_quaternion(&quat[0]);
621 std::copy(rot.begin(), rot.end(), bundle_cam->rot);
622 std::copy(trans.begin(), trans.end(), bundle_cam->trans);
623}
624
625void
627 std::string const& image_path,
628 std::string& image_name,
629 std::string const& depth_path,
630 std::string& depth_map_name,
631 AdditionalCameraInfo* colmap_cam_info)
632{
633 colmap_cam_info->filename = image_name;
634 colmap_cam_info->depth_map_name = depth_map_name;
635 colmap_cam_info->radial_distortion = model.dist[0];
636 if (!util::fs::is_absolute(colmap_cam_info->filename))
637 colmap_cam_info->filename = util::fs::join_path(image_path,
638 colmap_cam_info->filename);
639 if (!util::fs::is_absolute(colmap_cam_info->depth_map_name))
640 colmap_cam_info->depth_map_name = util::fs::join_path(depth_path,
641 colmap_cam_info->depth_map_name);
642}
643
644void
645determine_depth_map_path(std::string const& depth_path, std::string& image_name,
646 std::string* depth_map_name)
647{
648 std::string geometric_depth_map_name = util::fs::join_path(
649 depth_path, image_name + ".geometric.bin");
650 std::string photometric_depth_map_name = util::fs::join_path(
651 depth_path, image_name + ".photometric.bin");
652
653 if (util::fs::file_exists(geometric_depth_map_name.c_str()))
654 *depth_map_name = geometric_depth_map_name;
655 else if (util::fs::file_exists(photometric_depth_map_name.c_str()))
656 *depth_map_name = photometric_depth_map_name;
657 else
658 *depth_map_name = "";
659}
660
661void
662load_colmap_images_txt(std::string const& images_filename,
663 std::string const& image_path,
664 std::string const& depth_path,
665 std::map<uint32_t, CameraInfo>& camera_colmap_id_to_model,
666 Bundle::Ptr& bundle,
667 std::map< int, std::vector<Bundle::Feature2D> >* view_id_to_features_2d,
668 std::vector<AdditionalCameraInfo>* camera_info)
669{
670 std::cout << "Colmap: Loading images.txt file..." << std::endl;
671 std::cout << "Colmap: image_path " << image_path << std::endl;
672 std::cout << "Colmap: depth_path " << depth_path << std::endl;
673 std::ifstream in_images(images_filename.c_str());
674 check_stream(in_images, images_filename);
675 consume_comment_lines(in_images);
676
677 Bundle::Cameras& bundle_cams = bundle->get_cameras();
678 std::vector<AdditionalCameraInfo> colmap_cams_info;
679 std::string image_line;
680 std::string point_2d_line;
681 math::Vec4d quat;
682 math::Vec3d trans;
683 int view_id; // starts at 0
684 uint32_t view_colmap_id; // starts at 1
685 uint32_t camera_colmap_id; // starts at 1
686 int feature_3d_colmap_id; // starts at 1
687 std::string image_name;
688 std::string depth_map_name;
689 while (std::getline(in_images, image_line))
690 {
691 AdditionalCameraInfo colmap_cam_info;
692 CameraInfo bundle_cam;
693 std::stringstream image_line_ss(image_line);
694 image_line_ss >> view_colmap_id
695 >> quat[0] >> quat[1] >> quat[2] >> quat[3]
696 >> trans[0] >> trans[1] >> trans[2]
697 >> camera_colmap_id >> image_name;
698 view_id = view_colmap_id - 1;
699 image_name = util::fs::sanitize_path(image_name);
700 CameraInfo model = camera_colmap_id_to_model.at(camera_colmap_id);
701 initialize_bundle_cam(model, quat, trans, &bundle_cam);
702 determine_depth_map_path(depth_path, image_name, &depth_map_name);
703 initialize_cam_info(model, image_path, image_name, depth_path,
704 depth_map_name, &colmap_cam_info);
705
706 std::string point_2d_line;
707 std::getline(in_images, point_2d_line);
708 std::stringstream point_2d_line_ss(point_2d_line);
709 while (!point_2d_line_ss.eof())
710 {
712 ref.view_id = view_id;
713 point_2d_line_ss >> ref.pos[0] >> ref.pos[1];
714 point_2d_line_ss >> feature_3d_colmap_id;
715 // A POINT2D that does not correspond to a POINT3D has a POINT3D_ID
716 // of -1
717 if (feature_3d_colmap_id == -1)
718 ref.feature_id = -1;
719 else
720 ref.feature_id = feature_3d_colmap_id - 1;
721 (*view_id_to_features_2d)[view_id].push_back(ref);
722 }
723 bundle_cams.push_back(bundle_cam);
724 colmap_cams_info.push_back(colmap_cam_info);
725 }
726 if (camera_info != nullptr)
727 std::swap(*camera_info, colmap_cams_info);
728 in_images.close();
729}
730
731void
732load_colmap_points_3D_txt(std::string const& points3D_filename,
733 std::map< int, std::vector<Bundle::Feature2D> >& view_id_to_features_2d,
734 Bundle::Ptr& bundle)
735{
736 std::cout << "Colmap: Loading points3D.txt file..." << std::endl;
737 std::ifstream in_points3D(points3D_filename.c_str());
738 check_stream(in_points3D, points3D_filename);
739 consume_comment_lines(in_points3D);
740 Bundle::Features& features = bundle->get_features();
741
742 std::size_t num_views = bundle->get_cameras().size();
743 int num_points_3d = 0;
744 std::string point_3d_line;
745 while (std::getline(in_points3D, point_3d_line))
746 {
747 std::stringstream point_3d_line_ss(point_3d_line);
748 Bundle::Feature3D feature_3d;
749 int r,g,b;
750 float e;
751 int feature_3d_id; // starts at 0
752 int feature_3d_colmap_id; // starts at 1
753 point_3d_line_ss >> feature_3d_colmap_id;
754 feature_3d_id = feature_3d_colmap_id - 1;
755 point_3d_line_ss >> feature_3d.pos[0]
756 >> feature_3d.pos[1]
757 >> feature_3d.pos[2];
758 point_3d_line_ss >> r >> g >> b;
759 feature_3d.color[0] = r / 255.0f;
760 feature_3d.color[1] = g / 255.0f;
761 feature_3d.color[2] = b / 255.0f;
762 point_3d_line_ss >> e;
763 if (point_3d_line_ss.eof())
764 continue;
765
766 std::size_t num_refs = 0;
767 std::vector<int> view_ids;
768 std::vector<Bundle::Feature2D> refs;
769 while (!point_3d_line_ss.eof())
770 {
771 int view_colmap_id; // starts at 1
772 int feature_2d_idx; // starts at 0
773 point_3d_line_ss >> view_colmap_id >> feature_2d_idx;
774 int view_id = view_colmap_id - 1;
775 // Make sure that each point only has a single observation per
776 // image, since MVE does not support multiple observations.
777 if (std::find(view_ids.begin(), view_ids.end(), view_id) !=
778 view_ids.end())
779 continue;
780 view_ids.push_back(view_id);
781 Bundle::Feature2D corresponding_feature = view_id_to_features_2d.at(
782 view_id).at(feature_2d_idx);
783 assert(corresponding_feature.feature_id == feature_3d_id);
785 ref.view_id = view_id;
786 ref.feature_id = feature_2d_idx;
787 ref.pos[0] = corresponding_feature.pos[0];
788 ref.pos[1] = corresponding_feature.pos[1];
789 refs.push_back(ref);
790 ++num_refs;
791 }
792
793 /* There should be at least 2 cameras that see the point. */
794 if (num_refs < 2 || num_refs > num_views)
795 {
796 throw util::Exception("Invalid number of feature refs: ",
797 util::string::get(num_refs));
798 }
799 feature_3d.refs = refs;
800 features.push_back(feature_3d);
801 ++num_points_3d;
802 }
803 in_points3D.close();
804}
805
806void
807read_colmap_cameras_bin_params(std::vector<float>& params,
808 std::string const& model, std::ifstream& in_cameras)
809{
810 if (model == "SIMPLE_PINHOLE")
811 params.resize(3);
812 else if (model == "PINHOLE" || model == "SIMPLE_RADIAL")
813 params.resize(4);
814 else
815 throw util::Exception("Unsupported camera model provided");
816 for (std::size_t param_idx = 0; param_idx < params.size(); ++param_idx)
817 params[param_idx] = util::system::read_binary_little_endian<double>(
818 &in_cameras);
819}
820
821void
822load_colmap_cameras_bin(std::string const& cameras_filename,
823 std::map<uint32_t, CameraInfo>& camera_colmap_id_to_info)
824{
826 std::cout << "Colmap: Loading cameras.bin file..." << std::endl;
828 std::ifstream in_cameras(cameras_filename.c_str());
829
830 uint32_t camera_colmap_id; // starts at 1
831 std::string model_name;
832 uint32_t width, height;
833 std::vector<float> params;
834 uint64_t num_cam_models = read_binary_little_endian<uint64_t>(&in_cameras);
835 for (uint64_t model_idx = 0; model_idx < num_cam_models; ++model_idx)
836 {
837 camera_colmap_id = read_binary_little_endian<camera_t>(&in_cameras);
838 camera_t model_code = read_binary_little_endian<int>(&in_cameras);
839 model_name = camera_model_code_to_name.at(model_code);
840 width = (uint32_t)read_binary_little_endian<uint64_t>(&in_cameras);
841 height = (uint32_t)read_binary_little_endian<uint64_t>(&in_cameras);
842 read_colmap_cameras_bin_params(params, model_name, in_cameras);
843 CameraInfo camera_info;
845 camera_info, model_name, params, width, height);
846 camera_colmap_id_to_info[camera_colmap_id] = camera_info;
847 }
848 in_cameras.close();
849}
850
851void
852read_image_name(std::istream* in_images, std::string* image_name)
853{
854 (*image_name) = "";
855 char nameChar;
856 do
857 {
858 in_images->read(&nameChar, 1);
859 if (nameChar != '\0')
860 (*image_name) += nameChar;
861 }
862 while (nameChar != '\0');
863}
864
865void
866load_colmap_images_bin(std::string const& images_filename,
867 std::string const& image_path,
868 std::string const& depth_path,
869 std::map<uint32_t, CameraInfo>& camera_colmap_id_to_model,
870 Bundle::Ptr& bundle,
871 std::map< int, std::vector<Bundle::Feature2D> >* view_id_to_features_2d,
872 std::vector<AdditionalCameraInfo>* camera_info)
873{
875 std::cout << "Colmap: Loading images.bin file..." << std::endl;
876 std::cout << "Colmap: image_path " << image_path << std::endl;
877 std::cout << "Colmap: depth_path " << depth_path << std::endl;
878 std::ifstream in_images(images_filename.c_str());
879 check_stream(in_images, images_filename);
880
881 Bundle::Cameras& bundle_cams = bundle->get_cameras();
882 std::vector<AdditionalCameraInfo> colmap_cams_info;
883 uint64_t num_views = read_binary_little_endian<uint64_t>(&in_images);
884 bundle_cams.reserve(num_views);
885 colmap_cams_info.reserve(num_views);
886
887 math::Vec4d quat;
888 math::Vec3d trans;
889 int view_id; // starts at 0
890 uint32_t view_colmap_id; // starts at 1
891 uint32_t camera_colmap_id; // starts at 1
892 int feature_3d_colmap_id; // starts at 1
893 std::string image_name;
894 std::string depth_map_name;
895 for (std::size_t view_index = 0; view_index < num_views; ++view_index)
896 {
897 AdditionalCameraInfo colmap_cam_info;
898 CameraInfo bundle_cam;
899 view_colmap_id = read_binary_little_endian<image_t>(&in_images);
900 view_id = view_colmap_id - 1;
901 quat[0] = read_binary_little_endian<double>(&in_images);
902 quat[1] = read_binary_little_endian<double>(&in_images);
903 quat[2] = read_binary_little_endian<double>(&in_images);
904 quat[3] = read_binary_little_endian<double>(&in_images);
905 trans[0] = read_binary_little_endian<double>(&in_images);
906 trans[1] = read_binary_little_endian<double>(&in_images);
907 trans[2] = read_binary_little_endian<double>(&in_images);
908 camera_colmap_id = read_binary_little_endian<camera_t>(&in_images);
909 read_image_name(&in_images, &image_name);
910 image_name = util::fs::sanitize_path(image_name);
911 CameraInfo model = camera_colmap_id_to_model.at(camera_colmap_id);
912 initialize_bundle_cam(model, quat, trans, &bundle_cam);
913 determine_depth_map_path(depth_path, image_name, &depth_map_name);
914 initialize_cam_info(model, image_path, image_name, depth_path,
915 depth_map_name, &colmap_cam_info);
916
917 const std::size_t num_points_2D = read_binary_little_endian<uint64_t>(
918 &in_images);
919 for (std::size_t point_2d_idx = 0; point_2d_idx < num_points_2D;
920 ++point_2d_idx)
921 {
923 ref.view_id = view_id;
924 ref.pos[0] = (float)read_binary_little_endian<double>(&in_images);
925 ref.pos[1] = (float)read_binary_little_endian<double>(&in_images);
926 // A POINT2D that does not correspond to a POINT3D has a POINT3D_ID
927 // of -1
928 feature_3d_colmap_id = (uint32_t)read_binary_little_endian<
929 point3D_t>(&in_images);
930 if (feature_3d_colmap_id == -1)
931 ref.feature_id = -1;
932 else
933 ref.feature_id = feature_3d_colmap_id - 1;
934 (*view_id_to_features_2d)[view_id].push_back(ref);
935 }
936 bundle_cams.push_back(bundle_cam);
937 colmap_cams_info.push_back(colmap_cam_info);
938 }
939 if (camera_info != nullptr)
940 std::swap(*camera_info, colmap_cams_info);
941 in_images.close();
942}
943
944void
945load_colmap_points_3D_bin(std::string const& points3D_filename,
946 std::map< int, std::vector<Bundle::Feature2D> >& view_id_to_features_2d,
947 Bundle::Ptr& bundle)
948{
950 std::cout << "Colmap: Loading points3D.bin file..." << std::endl;
951 std::ifstream in_points3D(points3D_filename.c_str());
952 check_stream(in_points3D, points3D_filename);
953
954 uint64_t num_features = read_binary_little_endian<uint64_t>(&in_points3D);
955 Bundle::Features& features = bundle->get_features();
956 features.reserve(num_features);
957 std::size_t num_views = bundle->get_cameras().size();
958 for (std::size_t feature_3d_idx = 0; feature_3d_idx < num_features;
959 ++feature_3d_idx)
960 {
961 Bundle::Feature3D feature_3d;
962 int r,g,b;
963 int feature_3d_id; // starts at 0
964 int feature_3d_colmap_id; // starts at 1
965 feature_3d_colmap_id = (uint32_t)read_binary_little_endian<point3D_t>(
966 &in_points3D);
967 feature_3d_id = feature_3d_colmap_id - 1; // Fix Colmap id
968 feature_3d.pos[0] = read_binary_little_endian<double>(&in_points3D);
969 feature_3d.pos[1] = read_binary_little_endian<double>(&in_points3D);
970 feature_3d.pos[2] = read_binary_little_endian<double>(&in_points3D);
971 r = read_binary_little_endian<uint8_t>(&in_points3D);
972 g = read_binary_little_endian<uint8_t>(&in_points3D);
973 b = read_binary_little_endian<uint8_t>(&in_points3D);
974 read_binary_little_endian<double>(&in_points3D); // read error
975 feature_3d.color[0] = r / 255.0f;
976 feature_3d.color[1] = g / 255.0f;
977 feature_3d.color[2] = b / 255.0f;
978
979 std::size_t num_refs = read_binary_little_endian<uint64_t>(
980 &in_points3D);
981 std::vector<int> view_ids;
982 std::vector<Bundle::Feature2D> refs;
983 for (std::size_t ref_idx = 0; ref_idx < num_refs; ++ref_idx)
984 {
985 uint32_t view_colmap_id; // starts at 1
986 int feature_2d_idx; // starts at 0
987 view_colmap_id = read_binary_little_endian<image_t>(&in_points3D);
988 int view_id = view_colmap_id - 1;
989 feature_2d_idx = read_binary_little_endian<point2D_t>(&in_points3D);
990 // Make sure that each point only has a single observation per
991 // image, since MVE does not support multiple observations.
992 if (std::find(view_ids.begin(), view_ids.end(),
993 view_id) != view_ids.end())
994 continue;
995 view_ids.push_back(view_id);
996 Bundle::Feature2D corresponding_feature = view_id_to_features_2d.at(
997 view_id).at(feature_2d_idx);
998 assert(corresponding_feature.feature_id == feature_3d_id);
1000 ref.view_id = view_id;
1001 ref.feature_id = feature_2d_idx;
1002 ref.pos[0] = corresponding_feature.pos[0];
1003 ref.pos[1] = corresponding_feature.pos[1];
1004 refs.push_back(ref);
1005 }
1006 num_refs = refs.size();
1007
1008 /* There should be at least 2 cameras that see the point. */
1009 if (num_refs < 2 || num_refs > num_views)
1010 {
1011 throw util::Exception("Invalid number of feature refs: ",
1012 util::string::get(num_refs));
1013 }
1014 feature_3d.refs = refs;
1015 features.push_back(feature_3d);
1016 }
1017 in_points3D.close();
1018}
1019
1020Bundle::Ptr
1021load_colmap_bundle (std::string const& workspace_path,
1022 std::vector<AdditionalCameraInfo>* camera_info)
1023{
1024 using util::fs::join_path;
1025 // https://github.com/colmap/colmap/blob/dev/src/base/reconstruction.cc
1026 // void Reconstruction::ReadText(const std::string& path)
1027 // void Reconstruction::ReadBinary(const std::string& path)
1028
1029 std::string model_path = join_path(workspace_path, "sparse");
1030 std::string image_path = join_path(workspace_path, "images");
1031 std::string stereo_path = join_path(workspace_path, "stereo");
1032 std::string depth_path = join_path(stereo_path, "depth_maps");
1033
1034 std::string cameras_txt_filename = join_path(model_path, "cameras.txt");
1035 std::string cameras_bin_filename = join_path(model_path, "cameras.bin");
1036
1037 std::string images_txt_filename = join_path(model_path, "images.txt");
1038 std::string images_bin_filename = join_path(model_path, "images.bin");
1039
1040 std::string points_3D_txt_filename = join_path(model_path, "points3D.txt");
1041 std::string points_3D_bin_filename = join_path(model_path, "points3D.bin");
1042
1043 std::cout << "Colmap: Loading workspace..." << std::endl;
1044 std::cout << workspace_path << std::endl;
1045 // The depth maps are optional
1046 if (!util::fs::dir_exists(model_path.c_str()))
1047 throw util::Exception("Sparse model directory missing: ",
1048 model_path);
1049 if (!util::fs::dir_exists(image_path.c_str()))
1050 throw util::Exception("Undistored image directory missing: ",
1051 image_path);
1052
1053 std::map<uint32_t, CameraInfo> camera_colmap_id_to_info;
1054 if (util::fs::file_exists(cameras_txt_filename.c_str()))
1056 cameras_txt_filename,
1057 camera_colmap_id_to_info);
1058 else
1060 cameras_bin_filename,
1061 camera_colmap_id_to_info);
1062
1063 Bundle::Ptr bundle_colmap = Bundle::create();
1064 std::map< int, std::vector<Bundle::Feature2D> > view_id_to_features_2d;
1065 std::vector<AdditionalCameraInfo> colmap_camera_info;
1066 if (util::fs::file_exists(images_txt_filename.c_str()))
1068 images_txt_filename,
1069 image_path,
1070 depth_path,
1071 camera_colmap_id_to_info,
1072 bundle_colmap,
1073 &view_id_to_features_2d,
1074 &colmap_camera_info);
1075 else
1077 images_bin_filename,
1078 image_path,
1079 depth_path,
1080 camera_colmap_id_to_info,
1081 bundle_colmap,
1082 &view_id_to_features_2d,
1083 &colmap_camera_info);
1084
1085 if (util::fs::file_exists(points_3D_txt_filename.c_str()))
1087 points_3D_txt_filename,
1088 view_id_to_features_2d,
1089 bundle_colmap);
1090 else
1092 points_3D_bin_filename,
1093 view_id_to_features_2d,
1094 bundle_colmap);
1095
1096 *camera_info = colmap_camera_info;
1097
1098 return bundle_colmap;
1099}
1100
1101/* -------------- Support for Colmap Depth Maps --------------- */
1102
1104parse_colmap_depth_map(const std::string& path)
1105{
1107 std::ifstream text_file(path, std::ios::binary);
1108
1109 if (!util::fs::file_exists(path.c_str()))
1110 {
1111 throw util::Exception("Depth map not found in ", path);
1112 }
1113
1114 size_t depth_map_width = 0;
1115 size_t depth_map_height = 0;
1116 size_t depth_map_depth = 0;
1117 char unused_char;
1118 text_file >> depth_map_width >> unused_char >> depth_map_height
1119 >> unused_char >> depth_map_depth >> unused_char;
1120 std::streampos pos = text_file.tellg();
1121 text_file.close();
1122
1123 assert(depth_map_width > 0);
1124 assert(depth_map_height > 0);
1125 assert(depth_map_depth == 1);
1126
1127 std::ifstream binary_file(path, std::ios::binary);
1128 binary_file.seekg(pos);
1129
1131 depth_map_width, depth_map_height, 1);
1132
1133 for (int i = 0; i < depth_img->get_pixel_amount(); ++i)
1134 depth_img->at(i) = read_binary_little_endian<float>(
1135 &binary_file);
1136
1137 binary_file.close();
1138 return depth_img;
1139}
1140
1142load_colmap_depth_map(int scale, mve::CameraInfo& mve_cam, int original_width,
1143 int original_height,
1144 mve::AdditionalCameraInfo const& cam_info)
1145{
1146 assert(scale >= 0);
1147
1149 cam_info.depth_map_name);
1150
1151 int depth_width = depth_image->width();
1152 int depth_height = depth_image->height();
1153
1154 math::Matrix3f inv_calib;
1155 mve_cam.fill_inverse_calibration(*inv_calib, original_width,
1156 original_height);
1157 mve::image::depthmap_convert_conventions<float>(depth_image, inv_calib,
1158 true);
1159
1160 if (depth_width == original_width && depth_height == original_height)
1161 {
1162 // Lossless resizing
1163 for (int i = 0; i < scale; ++i)
1165 float>(depth_image);
1166 }
1167 else
1168 {
1169 std::ostringstream string_stream;
1170 string_stream
1171 << "Colmap depth map of size " << depth_width << " x "
1172 << depth_height << " does not match the corresponding undistorted "
1173 << "image of size " << original_width << " x " << original_height
1174 << ". Re-compute the depth maps using Colmap without limiting the "
1175 << "depth map size.";
1176 throw util::Exception(string_stream.str().c_str());
1177 }
1178 return depth_image;
1179}
1180
Matrix class for arbitrary dimensions and types.
Definition matrix.h:54
T * end(void)
Definition matrix.h:520
T * begin(void)
Definition matrix.h:506
Vector class for arbitrary dimensions and types.
Definition vector.h:87
T * end(void)
Definition vector.h:597
T * begin(void)
Definition vector.h:583
std::vector< Feature3D > Features
Definition bundle.h:62
std::vector< CameraInfo > Cameras
Definition bundle.h:61
std::shared_ptr< Bundle > Ptr
Definition bundle.h:59
std::shared_ptr< Bundle const > ConstPtr
Definition bundle.h:60
std::shared_ptr< Image< T > > Ptr
Definition image.h:42
static Ptr create(void)
Smart pointer image constructor.
Definition image.h:191
Universal, simple exception class.
Definition exception.h:24
Exception class for file exceptions with additional filename.
Definition exception.h:53
#define MATH_ISINF(x)
Definition defines.h:105
#define MATH_ISNAN(x)
Definition defines.h:104
#define MVE_NAMESPACE_BEGIN
Definition defines.h:13
#define MVE_NAMESPACE_END
Definition defines.h:14
Image< T >::Ptr rescale_half_size_subsample(typename Image< T >::ConstPtr image)
Returns a rescaled version of the image by subsampling every second column and row.
uint64_t image_pair_t
Definition bundle_io.cc:494
Bundle::Ptr load_bundler_ps_intern(std::string const &filename, BundleFormat format)
Definition bundle_io.cc:276
void consume_comment_lines(std::ifstream &in)
Definition bundle_io.cc:523
uint64_t point3D_t
Definition bundle_io.cc:496
void determine_depth_map_path(std::string const &depth_path, std::string &image_name, std::string *depth_map_name)
Definition bundle_io.cc:645
void initialize_bundle_cam(CameraInfo &model, math::Vec4d &quat, math::Vec3d &trans, CameraInfo *bundle_cam)
Definition bundle_io.cc:609
void save_mve_bundle(Bundle::ConstPtr bundle, std::string const &filename)
TODO: For now refers to save_photosynther_bundle().
Definition bundle_io.cc:40
Bundle::Ptr load_bundler_bundle(std::string const &filename)
Loads a Bundler bundle file.
Definition bundle_io.cc:412
void load_colmap_cameras_txt(std::string const &cameras_filename, std::map< uint32_t, CameraInfo > &camera_colmap_id_to_info)
Definition bundle_io.cc:578
void read_image_name(std::istream *in_images, std::string *image_name)
Definition bundle_io.cc:852
void read_colmap_cameras_bin_params(std::vector< float > &params, std::string const &model, std::ifstream &in_cameras)
Definition bundle_io.cc:807
void load_colmap_points_3D_bin(std::string const &points3D_filename, std::map< int, std::vector< Bundle::Feature2D > > &view_id_to_features_2d, Bundle::Ptr &bundle)
Definition bundle_io.cc:945
void load_colmap_images_bin(std::string const &images_filename, std::string const &image_path, std::string const &depth_path, std::map< uint32_t, CameraInfo > &camera_colmap_id_to_model, Bundle::Ptr &bundle, std::map< int, std::vector< Bundle::Feature2D > > *view_id_to_features_2d, std::vector< AdditionalCameraInfo > *camera_info)
Definition bundle_io.cc:866
mve::FloatImage::Ptr load_colmap_depth_map(int scale, mve::CameraInfo &mve_cam, int original_width, int original_height, mve::AdditionalCameraInfo const &cam_info)
uint32_t point2D_t
Definition bundle_io.cc:495
void save_photosynther_bundle(Bundle::ConstPtr bundle, std::string const &filename)
Writes a Photosynther bundle file.
Definition bundle_io.cc:426
void load_colmap_cameras_bin(std::string const &cameras_filename, std::map< uint32_t, CameraInfo > &camera_colmap_id_to_info)
Definition bundle_io.cc:822
Bundle::Ptr load_photosynther_bundle(std::string const &filename)
Loads a Photosynther bundle file.
Definition bundle_io.cc:420
Bundle::Ptr load_mve_bundle(std::string const &filename)
TODO: For now refers to load_photosynther_bundle().
Definition bundle_io.cc:34
uint32_t camera_t
Definition bundle_io.cc:492
void create_camera_info_from_params(CameraInfo &camera_info, std::string const &model, std::vector< float > const &params, uint32_t width, uint32_t height)
Definition bundle_io.cc:533
void initialize_cam_info(CameraInfo &model, std::string const &image_path, std::string &image_name, std::string const &depth_path, std::string &depth_map_name, AdditionalCameraInfo *colmap_cam_info)
Definition bundle_io.cc:626
mve::FloatImage::Ptr parse_colmap_depth_map(const std::string &path)
Bundle::Ptr load_nvm_bundle(std::string const &filename, std::vector< AdditionalCameraInfo > *camera_info)
Loads an NVM bundle file while providing NVM specific information.
Definition bundle_io.cc:73
void load_colmap_points_3D_txt(std::string const &points3D_filename, std::map< int, std::vector< Bundle::Feature2D > > &view_id_to_features_2d, Bundle::Ptr &bundle)
Definition bundle_io.cc:732
std::map< camera_t, std::string > camera_model_code_to_name
Definition bundle_io.cc:498
Bundle::Ptr load_colmap_bundle(std::string const &workspace_path, std::vector< AdditionalCameraInfo > *camera_info)
void load_colmap_images_txt(std::string const &images_filename, std::string const &image_path, std::string const &depth_path, std::map< uint32_t, CameraInfo > &camera_colmap_id_to_model, Bundle::Ptr &bundle, std::map< int, std::vector< Bundle::Feature2D > > *view_id_to_features_2d, std::vector< AdditionalCameraInfo > *camera_info)
Definition bundle_io.cc:662
void define_camera_models()
Definition bundle_io.cc:501
uint32_t image_t
Definition bundle_io.cc:493
void check_stream(std::ifstream &in, std::string const &filename)
Definition bundle_io.cc:516
void swap(mve::Image< T > &a, mve::Image< T > &b)
Specialization of std::swap for efficient image swapping.
Definition image.h:478
std::string sanitize_path(std::string const &path)
Canonicalize slashes in the given path.
bool is_absolute(std::string const &path)
Checks whether the given path is absolute.
std::string dirname(std::string const &path)
Returns the directory name component of the given path.
bool dir_exists(char const *pathname)
Determines if the given path is a directory.
std::string join_path(std::string const &path1, std::string const &path2)
Concatenate and canonicalize two paths.
bool file_exists(char const *pathname)
Determines if the given path is a file.
void clip_newlines(std::string *str)
Clips newlines from the end of the string, in-place.
Definition strings.h:317
void clip_whitespaces(std::string *str)
Clips whitespaces from the front and end of the string, in-place.
Definition strings.h:299
std::string get(T const &value)
From arbitrary types to string conversion.
Definition strings.h:108
T read_binary_little_endian(std::istream *stream)
Reads little endian according to host order conversion.
Definition system.h:253
Per-camera NVM specific information.
Definition bundle_io.h:37
std::string filename
Path the original image file.
Definition bundle_io.h:39
float radial_distortion
The single radial distortion parameter.
Definition bundle_io.h:43
std::string depth_map_name
Path to a pre-computed depth map (optional).
Definition bundle_io.h:41
Representation of a 2D feature.
Definition bundle.h:34
Representation of a 3D feature with position and color.
Definition bundle.h:47
std::vector< Feature2D > refs
References to views that see the feature.
Definition bundle.h:53
float pos[3]
3D Position of the feature (track).
Definition bundle.h:49
float color[3]
RGB color of the feature in [0,1]^3.
Definition bundle.h:51
Per-view camera information with various helper functions.
Definition camera.h:24
float paspect
Pixel aspect ratio pixel_width / pixel_height.
Definition camera.h:160
float trans[3]
Camera translation vector.
Definition camera.h:167
float rot[9]
Camera rotation which transforms from world to cam.
Definition camera.h:169
float ppoint[2]
Principal point in x- and y-direction.
Definition camera.h:158
float flen
Focal length.
Definition camera.h:156
void fill_inverse_calibration(float *mat, float width, float height) const
Stores 3x3 inverse calibration (or inverse projection) matrix.
Definition camera.cc:180
float dist[2]
Image distortion parameters.
Definition camera.h:162