apps/txt2mm/main.cpp
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------
2  * A repertory of multi primitive-to-primitive (MP2P) ICP algorithms in C++
3  * Copyright (C) 2018-2024 Jose Luis Blanco, University of Almeria
4  * See LICENSE for license information.
5  * ------------------------------------------------------------------------- */
6 
14 #include <mp2p_icp/metricmap.h>
15 #include <mrpt/3rdparty/tclap/CmdLine.h>
16 #include <mrpt/maps/CColouredPointsMap.h>
17 #include <mrpt/maps/CPointsMapXYZI.h>
18 #include <mrpt/maps/CPointsMapXYZIRT.h>
19 #include <mrpt/maps/CSimplePointsMap.h>
20 #include <mrpt/math/CMatrixDynamic.h>
21 #include <mrpt/obs/CObservationPointCloud.h>
22 #include <mrpt/system/filesystem.h>
23 
24 const char* VALID_FORMATS = "(xyz|xyzi|xyzirt|xyzrgb)";
25 
26 using namespace std::string_literals;
27 
28 // CLI flags:
29 struct Cli
30 {
31  TCLAP::CmdLine cmd{"txt2mm"};
32 
33  TCLAP::ValueArg<std::string> argInput{
34  "i",
35  "input",
36  "Path to input TXT or CSV file. One point per row. Columns separated "
37  "by "
38  "spaces or commas. See docs for supported formats.",
39  true,
40  "input.txt",
41  "input.txt",
42  cmd};
43 
44  TCLAP::ValueArg<std::string> argOutput{
45  "o", "output", "Output file to write to.", true, "out.mm", "out.mm", cmd};
46 
47  TCLAP::ValueArg<std::string> argFormat{
48  "f",
49  "format",
50  "Point cloud format. Mandatory flag.\n"s
51  "Options: "s +
53  true,
54  "xyz",
56  cmd};
57 
58  TCLAP::ValueArg<std::string> argLayer{
59  "l", "layer", "Target layer name (Default: \"raw\").", false, "raw", "raw", cmd};
60 
61  TCLAP::ValueArg<int> argIndexXYZ{
62  "", "column-x", "Column index for the X coordinate in the input data (Default: 0).",
63  false, 0, "column index",
64  cmd};
65 
66  TCLAP::ValueArg<int> argIndexI{
67  "",
68  "column-i",
69  "Column index for the Intensity channel in the input data (Default: "
70  "3).",
71  false,
72  3,
73  "column index",
74  cmd};
75 
76  TCLAP::ValueArg<int> argIndexR{
77  "", "column-r", "Column index for the Ring channel in the input data (Default: 4).",
78  false, 4, "column index",
79  cmd};
80 
81  TCLAP::ValueArg<int> argIndexT{
82  "",
83  "column-t",
84  "Column index for the Timestamp channel in the input data (Default: "
85  "5).",
86  false,
87  5,
88  "column index",
89  cmd};
90 
91  TCLAP::ValueArg<uint64_t> argID{
92  "", "id", "Metric map numeric ID (Default: none).", false, 0, "[ID]", cmd};
93 
94  TCLAP::ValueArg<std::string> argLabel{
95  "", "label", "Metric map label string (Default: none).", false, "label", "[label]", cmd};
96 };
97 
98 int main(int argc, char** argv)
99 {
100  try
101  {
102  Cli cli;
103 
104  // Parse arguments:
105  if (!cli.cmd.parse(argc, argv)) return 1; // should exit.
106 
107  const auto& f = cli.argInput.getValue();
108  ASSERT_FILE_EXISTS_(f);
109 
110  std::cout << "Reading data from '" << f << "'..." << std::endl;
111 
112  mrpt::math::CMatrixFloat data;
113  data.loadFromTextFile(f);
114 
115  const size_t nRows = data.size().at(0), nCols = data.size().at(1);
116 
117  std::cout << "Done: " << nRows << " rows, " << nCols << " columns." << std::endl;
118 
119  mrpt::maps::CPointsMap::Ptr pc;
120  const auto format = cli.argFormat.getValue();
121 
122  const auto idxX = cli.argIndexXYZ.getValue();
123  const auto idxI = cli.argIndexI.getValue();
124  const auto idxR = cli.argIndexR.getValue();
125  const auto idxT = cli.argIndexT.getValue();
126 
127  if (format == "xyz")
128  {
129  ASSERT_GE_(nCols, 3U);
130  pc = mrpt::maps::CSimplePointsMap::Create();
131  pc->reserve(nRows);
132  if (nCols > 3)
133  std::cout << "Warning: Only the first 3 columns from the file "
134  "will be used for the output format 'xyz'"
135  << std::endl;
136 
137  for (size_t i = 0; i < nRows; i++)
138  pc->insertPointFast(data(i, idxX + 0), data(i, idxX + 1), data(i, idxX + 2));
139  }
140  else if (format == "xyzi")
141  {
142  ASSERT_GE_(nCols, 4U);
143  auto pts = mrpt::maps::CPointsMapXYZI::Create();
144  pts->reserve(nRows);
145  if (nCols > 4)
146  std::cout << "Warning: Only the first 4 columns from the file "
147  "will be used for the output format 'xyzi'"
148  << std::endl;
149 
150  for (size_t i = 0; i < nRows; i++)
151  {
152  pts->insertPointFast(data(i, idxX + 0), data(i, idxX + 1), data(i, idxX + 2));
153  pts->insertPointField_Intensity(data(i, idxI));
154  }
155 
156  pc = pts;
157  }
158  else if (format == "xyzirt")
159  {
160  ASSERT_GE_(nCols, 6U);
161  auto pts = mrpt::maps::CPointsMapXYZI::Create();
162  pts->reserve(nRows);
163  if (nCols > 6)
164  std::cout << "Warning: Only the first 6 columns from the file "
165  "will be used for the output format 'xyzirt'"
166  << std::endl;
167 
168  for (size_t i = 0; i < nRows; i++)
169  {
170  pts->insertPointFast(data(i, idxX + 0), data(i, idxX + 1), data(i, idxX + 2));
171  pts->insertPointField_Intensity(data(i, idxI));
172  pts->insertPointField_Ring(data(i, idxR));
173  pts->insertPointField_Timestamp(data(i, idxT));
174  }
175 
176  pc = pts;
177  }
178  else if (format == "xyzrgb")
179  {
180  ASSERT_GE_(nCols, 6U);
181  auto pts = mrpt::maps::CColouredPointsMap::Create();
182  pts->reserve(nRows);
183  if (nCols > 6)
184  std::cout << "Warning: Only the first 6 columns from the file "
185  "will be used for the output format 'xyzrgb'"
186  << std::endl;
187 
188  const size_t idxRed = 3, idxGreen = 4, idxBlue = 5;
189 
190  for (size_t i = 0; i < nRows; i++)
191  {
192  pts->insertPointFast(data(i, idxX + 0), data(i, idxX + 1), data(i, idxX + 2));
193  pts->insertPointField_color_R(mrpt::u8tof(data(i, idxRed)));
194  pts->insertPointField_color_G(mrpt::u8tof(data(i, idxGreen)));
195  pts->insertPointField_color_B(mrpt::u8tof(data(i, idxBlue)));
196  }
197 
198  pc = pts;
199  }
200  else
201  {
202  THROW_EXCEPTION_FMT(
203  "Invalid --format set to '%s'. Valid values: %s", format.c_str(), VALID_FORMATS);
204  }
205 
206  // Save as mm file:
208  mm.layers["raw"] = std::move(pc);
209 
210  if (cli.argID.isSet()) mm.id = cli.argID.getValue();
211  if (cli.argLabel.isSet()) mm.label = cli.argLabel.getValue();
212 
213  std::cout << "Map contents: " << mm.contents_summary() << std::endl;
214  std::cout << "Saving map to: " << cli.argOutput.getValue() << std::endl;
215 
216  if (!mm.save_to_file(cli.argOutput.getValue()))
217  THROW_EXCEPTION_FMT(
218  "Error writing to target file '%s'", cli.argOutput.getValue().c_str());
219  }
220  catch (const std::exception& e)
221  {
222  std::cerr << mrpt::exception_to_str(e);
223  return 1;
224  }
225  return 0;
226 }
cli
std::unique_ptr< cli_flags > cli
Definition: sm-cli-main.cpp:29
argLayer
static TCLAP::ValueArg< std::string > argLayer("l", "layer", "Target layer name (Default: \"raw\").", false, "raw", "raw", cmd)
s
XmlRpcServer s
kitti-run-seq.f
string f
Definition: kitti-run-seq.py:12
mp2p_icp::metric_map_t::save_to_file
bool save_to_file(const std::string &fileName) const
Definition: metricmap.cpp:545
kitti-run-seq.cmd
string cmd
Definition: kitti-run-seq.py:14
argInput
static TCLAP::ValueArg< std::string > argInput("i", "input", "KITTI .bin pointcloud file.", true, "kitti-00.bin", "kitti-00.bin", cmd)
mp2p_icp::metric_map_t::label
std::optional< std::string > label
Definition: metricmap.h:101
Cli
Definition: apps/rawlog-filter/main.cpp:28
main
int main(int argc, char **argv)
Definition: apps/txt2mm/main.cpp:98
mp2p_icp::metric_map_t::contents_summary
virtual std::string contents_summary() const
Definition: metricmap.cpp:481
argOutput
static TCLAP::ValueArg< std::string > argOutput("o", "output", "Output file to write to.", true, "out.mm", "out.mm", cmd)
argID
static TCLAP::ValueArg< uint64_t > argID("", "id", "Metric map numeric ID (Default: none).", false, 0, "[ID]", cmd)
VALID_FORMATS
const char * VALID_FORMATS
Definition: apps/txt2mm/main.cpp:24
metricmap.h
Generic representation of pointcloud(s) and/or extracted features.
mp2p_icp::metric_map_t
Generic container of pointcloud(s), extracted features and other maps.
Definition: metricmap.h:55
mp2p_icp::metric_map_t::id
std::optional< uint64_t > id
Definition: metricmap.h:94
argLabel
static TCLAP::ValueArg< std::string > argLabel("", "label", "Metric map label string (Default: none).", false, "label", "[label]", cmd)
mp2p_icp::metric_map_t::layers
std::map< layer_name_t, mrpt::maps::CMetricMap::Ptr > layers
Definition: metricmap.h:82


mp2p_icp
Author(s):
autogenerated on Mon May 26 2025 02:45:49