elch.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2011, Willow Garage, Inc.
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of the copyright holder(s) nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * $Id$
00037  *
00038  */
00039 
00040 #include <pcl/console/parse.h>
00041 #include <pcl/io/pcd_io.h>
00042 #include <pcl/point_types.h>
00043 #include <pcl/common/transforms.h>
00044 #include <pcl/registration/icp.h>
00045 #include <pcl/registration/elch.h>
00046 
00047 #include <iostream>
00048 #include <string>
00049 
00050 #include <vector>
00051 
00052 typedef pcl::PointXYZ PointType;
00053 typedef pcl::PointCloud<PointType> Cloud;
00054 typedef Cloud::ConstPtr CloudConstPtr;
00055 typedef Cloud::Ptr CloudPtr;
00056 typedef std::pair<std::string, CloudPtr> CloudPair;
00057 typedef std::vector<CloudPair> CloudVector;
00058 
00059 bool
00060 loopDetection (int end, const CloudVector &clouds, double dist, int &first, int &last)
00061 {
00062   static double min_dist = -1;
00063   int state = 0;
00064 
00065   for (int i = end-1; i > 0; i--)
00066   {
00067     Eigen::Vector4f cstart, cend;
00068     //TODO use pose of scan
00069     pcl::compute3DCentroid (*(clouds[i].second), cstart);
00070     pcl::compute3DCentroid (*(clouds[end].second), cend);
00071     Eigen::Vector4f diff = cend - cstart;
00072 
00073     double norm = diff.norm ();
00074 
00075     //std::cout << "distance between " << i << " and " << end << " is " << norm << " state is " << state << std::endl;
00076 
00077     if (state == 0 && norm > dist)
00078     {
00079       state = 1;
00080       //std::cout << "state 1" << std::endl;
00081     }
00082     if (state > 0 && norm < dist)
00083     {
00084       state = 2;
00085       //std::cout << "loop detected between scan " << i << " (" << clouds[i].first << ") and scan " << end << " (" << clouds[end].first << ")" << std::endl;
00086       if (min_dist < 0 || norm < min_dist)
00087       {
00088         min_dist = norm;
00089         first = i;
00090         last = end;
00091       }
00092     }
00093   }
00094   //std::cout << "min_dist: " << min_dist << " state: " << state << " first: " << first << " end: " << end << std::endl;
00095   if (min_dist > 0 && (state < 2 || end == int (clouds.size ()) - 1)) //TODO
00096   {
00097     min_dist = -1;
00098     return true;
00099   }
00100   return false;
00101 }
00102 
00103 int
00104 main (int argc, char **argv)
00105 {
00106   double dist = 0.1;
00107   pcl::console::parse_argument (argc, argv, "-d", dist);
00108 
00109   double rans = 0.1;
00110   pcl::console::parse_argument (argc, argv, "-r", rans);
00111 
00112   int iter = 100;
00113   pcl::console::parse_argument (argc, argv, "-i", iter);
00114 
00115   pcl::registration::ELCH<PointType> elch;
00116   pcl::IterativeClosestPoint<PointType, PointType>::Ptr icp (new pcl::IterativeClosestPoint<PointType, PointType>);
00117   icp->setMaximumIterations (iter);
00118   icp->setMaxCorrespondenceDistance (dist);
00119   icp->setRANSACOutlierRejectionThreshold (rans);
00120   elch.setReg (icp);
00121 
00122   std::vector<int> pcd_indices;
00123   pcd_indices = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");
00124 
00125   CloudVector clouds;
00126   for (size_t i = 0; i < pcd_indices.size (); i++)
00127   {
00128     CloudPtr pc (new Cloud);
00129     pcl::io::loadPCDFile (argv[pcd_indices[i]], *pc);
00130     clouds.push_back (CloudPair (argv[pcd_indices[i]], pc));
00131     std::cout << "loading file: " << argv[pcd_indices[i]] << " size: " << pc->size () << std::endl;
00132     elch.addPointCloud (clouds[i].second);
00133   }
00134 
00135   int first = 0, last = 0;
00136 
00137   for (size_t i = 0; i < clouds.size (); i++)
00138   {
00139 
00140     if (loopDetection (int (i), clouds, 3.0, first, last))
00141     {
00142       std::cout << "Loop between " << first << " (" << clouds[first].first << ") and " << last << " (" << clouds[last].first << ")" << std::endl;
00143       elch.setLoopStart (first);
00144       elch.setLoopEnd (last);
00145       elch.compute ();
00146     }
00147   }
00148 
00149   for (size_t i = 0; i < clouds.size (); i++)
00150   {
00151     std::string result_filename (clouds[i].first);
00152     result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
00153     pcl::io::savePCDFileBinary (result_filename.c_str (), *(clouds[i].second));
00154     std::cout << "saving result to " << result_filename << std::endl;
00155   }
00156 
00157   return 0;
00158 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:23:26