56 string& outputBaseFile,
57 string& initTranslation,
string& initRotation);
59 const int cloudDimension);
61 const int cloudDimension);
63 void usage(
const char *argv[]);
72 int main(
int argc,
const char *argv[])
74 bool isTransfoSaved =
false;
75 bool isVerbose =
false;
77 string outputBaseFile(
"test");
78 string initTranslation(
"0,0,0");
79 string initRotation(
"1,0,0;0,1,0;0,0,1");
80 const int ret =
validateArgs(argc, argv, isVerbose, isTransfoSaved, configFile,
81 outputBaseFile, initTranslation, initRotation);
86 const char *refFile(argv[argc-2]);
87 const char *dataFile(argv[argc-1]);
97 if (configFile.empty())
105 ifstream ifs(configFile.c_str());
108 cerr <<
"Cannot open config file " << configFile <<
", usage:";
usage(argv); exit(1);
110 icp.loadFromYaml(ifs);
114 int cloudDimension =
ref.getEuclideanDim();
116 if (!(cloudDimension == 2 || cloudDimension == 3))
118 cerr <<
"Invalid input point clouds dimension" << endl;
130 std::shared_ptr<PM::Transformation> rigidTrans;
133 if (!rigidTrans->checkParameters(initTransfo)) {
135 <<
"Initial transformation is not rigid, identiy will be used"
137 initTransfo = PM::TransformationParameters::Identity(
138 cloudDimension+1,cloudDimension+1);
141 const DP initializedData = rigidTrans->compute(
data, initTransfo);
146 cout <<
"match ratio: " <<
icp.errorMinimizer->getWeightedPointUsedRatio() << endl;
153 ref.save(outputBaseFile +
"_ref.vtk");
154 data.save(outputBaseFile +
"_data_in.vtk");
155 data_out.save(outputBaseFile +
"_data_out.vtk");
157 ofstream transfoFile;
158 string initFileName = outputBaseFile +
"_init_transfo.txt";
159 string icpFileName = outputBaseFile +
"_icp_transfo.txt";
160 string completeFileName = outputBaseFile +
"_complete_transfo.txt";
162 transfoFile.open(initFileName.c_str());
163 if(transfoFile.is_open()) {
164 transfoFile << initTransfo << endl;
167 cerr <<
"Unable to write the initial transformation file\n" << endl;
170 transfoFile.open(icpFileName.c_str());
171 if(transfoFile.is_open()) {
172 transfoFile <<
T << endl;
175 cerr <<
"Unable to write the ICP transformation file\n" << endl;
178 transfoFile.open(completeFileName.c_str());
179 if(transfoFile.is_open()) {
180 transfoFile <<
T*initTransfo << endl;
183 cerr <<
"Unable to write the complete transformation file\n" << endl;
189 cout <<
"ICP transformation:" << endl <<
T << endl;
200 cout <<
"* " <<
name <<
" *\n" << endl;
201 for (BOOST_AUTO(it, registrar.begin()); it != registrar.end(); ++it)
203 cout << it->first << endl;
205 cout << it->second->availableParameters() << endl;
210 #define DUMP_REGISTRAR_CONTENT(pm, name, bib) \
211 dumpRegistrar(pm, pm.REG(name), # name, bib);
226 cout <<
"* Bibliography *" << endl << endl;
233 bool& isTransfoSaved,
235 string& outputBaseFile,
236 string& initTranslation,
string& initRotation)
240 cerr <<
"Not enough arguments, usage:";
246 if (
string(argv[1]) ==
"-l")
253 cerr <<
"Wrong option, usage:";
259 const int endOpt(argc - 2);
260 for (
int i = 1; i < endOpt; i += 2)
262 const string opt(argv[i]);
263 if (opt ==
"--verbose" || opt ==
"-v") {
270 cerr <<
"Missing value for option " << opt <<
", usage:";
usage(argv); exit(1);
272 if (opt ==
"--isTransfoSaved") {
273 if (strcmp(argv[i+1],
"1") == 0 || strcmp(argv[i+1],
"true") == 0) {
274 isTransfoSaved =
true;
276 else if (strcmp(argv[i+1],
"0") == 0
277 || strcmp(argv[i+1],
"false") == 0) {
278 isTransfoSaved =
false;
281 cerr <<
"Invalid value for parameter isTransfoSaved." << endl
282 <<
"Value must be true or false or 1 or 0." << endl
283 <<
"Default value will be used." << endl;
286 else if (opt ==
"--config") {
287 configFile = argv[i+1];
289 else if (opt ==
"--output") {
290 outputBaseFile = argv[i+1];
292 else if (opt ==
"--initTranslation") {
293 initTranslation = argv[i+1];
295 else if (opt ==
"--initRotation") {
296 initRotation = argv[i+1];
300 cerr <<
"Unknown option " << opt <<
", usage:";
usage(argv); exit(1);
307 const int cloudDimension) {
309 parsedTranslation = PM::TransformationParameters::Identity(
310 cloudDimension+1,cloudDimension+1);
319 float translationValues[3] = {0};
321 for(
int i = 0; i < cloudDimension; i++) {
322 if(!(translationStringStream >> translationValues[i])) {
323 cerr <<
"An error occured while trying to parse the initial "
324 <<
"translation." << endl
325 <<
"No initial translation will be used" << endl;
326 return parsedTranslation;
329 float extraOutput = 0;
330 if((translationStringStream >> extraOutput)) {
331 cerr <<
"Wrong initial translation size" << endl
332 <<
"No initial translation will be used" << endl;
333 return parsedTranslation;
336 for(
int i = 0; i < cloudDimension; i++) {
337 parsedTranslation(i,cloudDimension) = translationValues[i];
340 return parsedTranslation;
344 const int cloudDimension){
346 parsedRotation = PM::TransformationParameters::Identity(
347 cloudDimension+1,cloudDimension+1);
356 float rotationMatrix[9] = {0};
357 stringstream rotationStringStream(
rotation);
358 for(
int i = 0; i < cloudDimension*cloudDimension; i++) {
359 if(!(rotationStringStream >> rotationMatrix[i])) {
360 cerr <<
"An error occured while trying to parse the initial "
361 <<
"rotation." << endl
362 <<
"No initial rotation will be used" << endl;
363 return parsedRotation;
366 float extraOutput = 0;
367 if((rotationStringStream >> extraOutput)) {
368 cerr <<
"Wrong initial rotation size" << endl
369 <<
"No initial rotation will be used" << endl;
370 return parsedRotation;
373 for(
int i = 0; i < cloudDimension*cloudDimension; i++) {
374 parsedRotation(i/cloudDimension,i%cloudDimension) = rotationMatrix[i];
377 return parsedRotation;
384 cerr << endl << endl;
385 cerr <<
"* To list modules:" << endl;
386 cerr <<
" " << argv[0] <<
" -l" << endl;
388 cerr <<
"* To run ICP:" << endl;
389 cerr <<
" " << argv[0] <<
" [OPTIONS] reference.csv reading.csv" << endl;
391 cerr <<
"OPTIONS can be a combination of:" << endl;
392 cerr <<
"-v,--verbose Be more verbose (info logging to stdout)" << endl;
393 cerr <<
"--config YAML_CONFIG_FILE Load the config from a YAML file (default: default parameters)" << endl;
394 cerr <<
"--output BASEFILENAME Name of output files (default: test)" << endl;
395 cerr <<
"--initTranslation [x,y,z] Add an initial 3D translation before applying ICP (default: 0,0,0)" << endl;
396 cerr <<
"--initTranslation [x,y] Add an initial 2D translation before applying ICP (default: 0,0)" << endl;
397 cerr <<
"--initRotation [r00,r01,r02,r10,r11,r12,r20,r21,r22]" << endl;
398 cerr <<
" Add an initial 3D rotation before applying ICP (default: 1,0,0,0,1,0,0,0,1)" << endl;
399 cerr <<
"--initRotation [r00,r01,r10,r11]" << endl;
400 cerr <<
" Add an initial 2D rotation before applying ICP (default: 1,0,0,1)" << endl;
401 cerr <<
"--isTransfoSaved BOOL Save transformation matrix in three different files:" << endl;
402 cerr <<
" - BASEFILENAME_inti_transfo.txt" << endl;
403 cerr <<
" - BASEFILENAME_icp_transfo.txt" << endl;
404 cerr <<
" - BASEFILENAME_complete_transfo.txt" << endl;
405 cerr <<
" (default: false)" << endl;
407 cerr <<
"Running this program with a VTKFileInspector as Inspector will create three" << endl;
408 cerr <<
"vtk ouptput files: ./test_ref.vtk, ./test_data_in.vtk and ./test_data_out.vtk" << endl;
409 cerr << endl <<
"2D Example:" << endl;
410 cerr <<
" " << argv[0] <<
" ../examples/data/2D_twoBoxes.csv ../examples/data/2D_oneBox.csv" << endl;
411 cerr << endl <<
"3D Example:" << endl;
412 cerr <<
" " << argv[0] <<
" ../examples/data/car_cloud400.csv ../examples/data/car_cloud401.csv" << endl;