1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // The MIT License (MIT)
5 //
6 // Copyright (c) 2018 www.open3d.org
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 // IN THE SOFTWARE.
25 // ----------------------------------------------------------------------------
26
27 #include <iostream>
28 #include <memory>
29
30 #include <Eigen/Dense>
31 #include <Core/Core.h>
32 #include <IO/IO.h>
33 #include <Visualization/Visualization.h>
34
ReadLogFile(const std::string & filename,std::vector<std::tuple<int,int,int>> & metadata,std::vector<Eigen::Matrix4d> & transformations)35 bool ReadLogFile(const std::string &filename,
36 std::vector<std::tuple<int, int, int>> &metadata,
37 std::vector<Eigen::Matrix4d> &transformations)
38 {
39 using namespace three;
40 metadata.clear();
41 transformations.clear();
42 FILE * f = fopen(filename.c_str(), "r");
43 if (f == NULL) {
44 PrintWarning("Read LOG failed: unable to open file.\n");
45 return false;
46 }
47 char line_buffer[DEFAULT_IO_BUFFER_SIZE];
48 int i, j, k;
49 Eigen::Matrix4d trans;
50 while (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f)) {
51 if (strlen(line_buffer) > 0 && line_buffer[0] != '#') {
52 if (sscanf(line_buffer, "%d %d %d", &i, &j, &k) != 3) {
53 PrintWarning("Read LOG failed: unrecognized format.\n");
54 return false;
55 }
56 if (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f) == 0) {
57 PrintWarning("Read LOG failed: unrecognized format.\n");
58 return false;
59 } else {
60 sscanf(line_buffer, "%lf %lf %lf %lf", &trans(0,0), &trans(0,1),
61 &trans(0,2), &trans(0,3));
62 }
63 if (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f) == 0) {
64 PrintWarning("Read LOG failed: unrecognized format.\n");
65 return false;
66 } else {
67 sscanf(line_buffer, "%lf %lf %lf %lf", &trans(1,0), &trans(1,1),
68 &trans(1,2), &trans(1,3));
69 }
70 if (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f) == 0) {
71 PrintWarning("Read LOG failed: unrecognized format.\n");
72 return false;
73 } else {
74 sscanf(line_buffer, "%lf %lf %lf %lf", &trans(2,0), &trans(2,1),
75 &trans(2,2), &trans(2,3));
76 }
77 if (fgets(line_buffer, DEFAULT_IO_BUFFER_SIZE, f) == 0) {
78 PrintWarning("Read LOG failed: unrecognized format.\n");
79 return false;
80 } else {
81 sscanf(line_buffer, "%lf %lf %lf %lf", &trans(3,0), &trans(3,1),
82 &trans(3,2), &trans(3,3));
83 }
84 metadata.push_back(std::make_tuple(i, j, k));
85 transformations.push_back(trans);
86 }
87 }
88 fclose(f);
89 return true;
90 }
91
PrintHelp()92 void PrintHelp()
93 {
94 printf("Open3D %s\n", OPEN3D_VERSION);
95 printf("\n");
96 printf("Usage:\n");
97 printf(" > ViewPCDMatch [options]\n");
98 printf(" View pairwise matching result of point clouds.\n");
99 printf("\n");
100 printf("Basic options:\n");
101 printf(" --help, -h : Print help information.\n");
102 printf(" --log file : A log file of the pairwise matching results. Must have.\n");
103 printf(" --dir directory : The directory storing all pcd files. By default it is the parent directory of the log file + pcd/.\n");
104 printf(" --verbose n : Set verbose level (0-4). Default: 2.\n");
105 }
106
main(int argc,char * argv[])107 int main(int argc, char *argv[])
108 {
109 using namespace three;
110
111 if (argc <= 1 || ProgramOptionExists(argc, argv, "--help") ||
112 ProgramOptionExists(argc, argv, "-h")) {
113 PrintHelp();
114 return 0;
115 }
116 const int NUM_OF_COLOR_PALETTE = 5;
117 Eigen::Vector3d color_palette[NUM_OF_COLOR_PALETTE] = {
118 Eigen::Vector3d(255, 180, 0) / 255.0,
119 Eigen::Vector3d(0, 166, 237) / 255.0,
120 Eigen::Vector3d(246, 81, 29) / 255.0,
121 Eigen::Vector3d(127, 184, 0) / 255.0,
122 Eigen::Vector3d(13, 44, 84) / 255.0,
123 };
124
125 int verbose = GetProgramOptionAsInt(argc, argv, "--verbose", 2);
126 SetVerbosityLevel((VerbosityLevel)verbose);
127 std::string log_filename = GetProgramOptionAsString(argc, argv, "--log");
128 std::string pcd_dirname = GetProgramOptionAsString(argc, argv, "--dir");
129 if (pcd_dirname.empty()) {
130 pcd_dirname = filesystem::GetFileParentDirectory(log_filename) +
131 "pcds/";
132 }
133
134 std::vector<std::tuple<int, int, int>> metadata;
135 std::vector<Eigen::Matrix4d> transformations;
136 ReadLogFile(log_filename, metadata, transformations);
137
138 for (auto k = 0; k < metadata.size(); k++) {
139 auto i = std::get<0>(metadata[k]), j = std::get<1>(metadata[k]);
140 PrintInfo("Showing matched point cloud #%d and #%d.\n", i, j);
141 auto pcd_target = CreatePointCloudFromFile(pcd_dirname + "cloud_bin_" +
142 std::to_string(i) + ".pcd");
143 pcd_target->colors_.clear();
144 pcd_target->colors_.resize(pcd_target->points_.size(),
145 color_palette[0]);
146 auto pcd_source = CreatePointCloudFromFile(pcd_dirname + "cloud_bin_" +
147 std::to_string(j) + ".pcd");
148 pcd_source->colors_.clear();
149 pcd_source->colors_.resize(pcd_source->points_.size(),
150 color_palette[1]);
151 pcd_source->Transform(transformations[k]);
152 DrawGeometriesWithCustomAnimation({pcd_target, pcd_source},
153 "ViewPCDMatch", 1600, 900);
154 }
155 return 1;
156 }
157