manual_registration.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) 2010-2012, 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 Willow Garage, Inc. 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  * @author: Koen Buys - KU Leuven
00039  */
00040 
00041 #include <pcl/apps/manual_registration.h>
00042 
00043 //QT4
00044 #include <QApplication>
00045 #include <QMutexLocker>
00046 #include <QEvent>
00047 #include <QObject>
00048 
00049 // VTK
00050 #include <vtkRenderWindow.h>
00051 #include <vtkRendererCollection.h>
00052 #include <vtkCamera.h>
00053 
00054 using namespace pcl;
00055 using namespace std;
00056 
00058 ManualRegistration::ManualRegistration ()
00059 {
00060   //Create a timer
00061   vis_timer_ = new QTimer (this);
00062   vis_timer_->start (5);//5ms
00063 
00064   connect (vis_timer_, SIGNAL (timeout ()), this, SLOT (timeoutSlot()));
00065 
00066   ui_ = new Ui::MainWindow;
00067   ui_->setupUi (this);
00068   
00069   this->setWindowTitle ("PCL Manual Registration");
00070 
00071   // Set up the source window
00072   vis_src_.reset (new pcl::visualization::PCLVisualizer ("", false));
00073   ui_->qvtk_widget_src->SetRenderWindow (vis_src_->getRenderWindow ());
00074   vis_src_->setupInteractor (ui_->qvtk_widget_src->GetInteractor (), ui_->qvtk_widget_src->GetRenderWindow ());
00075   vis_src_->getInteractorStyle ()->setKeyboardModifier (pcl::visualization::INTERACTOR_KB_MOD_SHIFT);
00076   ui_->qvtk_widget_src->update ();
00077 
00078   vis_src_->registerPointPickingCallback (&ManualRegistration::SourcePointPickCallback, *this);
00079 
00080   // Set up the destination window
00081   vis_dst_.reset (new pcl::visualization::PCLVisualizer ("", false));
00082   ui_->qvtk_widget_dst->SetRenderWindow (vis_dst_->getRenderWindow ());
00083   vis_dst_->setupInteractor (ui_->qvtk_widget_dst->GetInteractor (), ui_->qvtk_widget_dst->GetRenderWindow ());
00084   vis_dst_->getInteractorStyle ()->setKeyboardModifier (pcl::visualization::INTERACTOR_KB_MOD_SHIFT);
00085   ui_->qvtk_widget_dst->update ();
00086 
00087   vis_dst_->registerPointPickingCallback (&ManualRegistration::DstPointPickCallback, *this);
00088 
00089 
00090   // Connect all buttons
00091   connect (ui_->confirmSrcPointButton, SIGNAL(clicked()), this, SLOT(confirmSrcPointPressed()));
00092   connect (ui_->confirmDstPointButton, SIGNAL(clicked()), this, SLOT(confirmDstPointPressed()));
00093   connect (ui_->calculateButton, SIGNAL(clicked()), this, SLOT(calculatePressed()));
00094   connect (ui_->clearButton, SIGNAL(clicked()), this, SLOT(clearPressed()));
00095   connect (ui_->orthoButton, SIGNAL(stateChanged(int)), this, SLOT(orthoChanged(int)));
00096   connect (ui_->applyTransformButton, SIGNAL(clicked()), this, SLOT(applyTransformPressed()));
00097   connect (ui_->refineButton, SIGNAL(clicked()), this, SLOT(refinePressed()));
00098   connect (ui_->undoButton, SIGNAL(clicked()), this, SLOT(undoPressed()));
00099   connect (ui_->safeButton, SIGNAL(clicked()), this, SLOT(safePressed()));
00100 
00101   cloud_src_modified_ = true; // first iteration is always a new pointcloud
00102   cloud_dst_modified_ = true;
00103 }
00104 
00105 void
00106 ManualRegistration::SourcePointPickCallback (const pcl::visualization::PointPickingEvent& event, void*)
00107 {
00108   // Check to see if we got a valid point. Early exit.
00109   int idx = event.getPointIndex ();
00110   if (idx == -1)
00111     return;
00112 
00113   // Get the point that was picked
00114   event.getPoint (src_point_.x, src_point_.y, src_point_.z);
00115   PCL_INFO ("Src Window: Clicked point %d with X:%f Y:%f Z:%f\n", idx, src_point_.x, src_point_.y, src_point_.z);
00116   src_point_selected_ = true;
00117 }
00118 
00119 void
00120 ManualRegistration::DstPointPickCallback (const pcl::visualization::PointPickingEvent& event, void*)
00121 {
00122   // Check to see if we got a valid point. Early exit.
00123   int idx = event.getPointIndex ();
00124   if (idx == -1)
00125     return;
00126 
00127   // Get the point that was picked
00128   event.getPoint (dst_point_.x, dst_point_.y, dst_point_.z);
00129   PCL_INFO ("Dst Window: Clicked point %d with X:%f Y:%f Z:%f\n", idx, dst_point_.x, dst_point_.y, dst_point_.z);
00130   dst_point_selected_ = true;
00131 }
00132 
00133 void 
00134 ManualRegistration::confirmSrcPointPressed()
00135 {
00136   if(src_point_selected_)
00137   {
00138     src_pc_.points.push_back(src_point_);
00139     PCL_INFO ("Selected %d source points\n", src_pc_.points.size());
00140     src_point_selected_ = false;
00141     src_pc_.width = src_pc_.points.size();
00142   }
00143   else
00144   {
00145     PCL_INFO ("Please select a point in the source window first\n");
00146   }
00147 }
00148 
00149 void 
00150 ManualRegistration::confirmDstPointPressed()
00151 {
00152   if(dst_point_selected_)
00153   {
00154     dst_pc_.points.push_back(dst_point_);
00155     PCL_INFO ("Selected %d destination points\n", dst_pc_.points.size());
00156     dst_point_selected_ = false;
00157     dst_pc_.width = dst_pc_.points.size();
00158   }
00159   else
00160   {
00161     PCL_INFO ("Please select a point in the destination window first\n");
00162   }
00163 }
00164 
00165 void 
00166 ManualRegistration::calculatePressed()
00167 {
00168   if(dst_pc_.points.size() != src_pc_.points.size())
00169   {
00170     PCL_INFO ("You haven't selected an equal amount of points, please do so\n");
00171     return;
00172   }
00173   pcl::registration::TransformationEstimationSVD<pcl::PointXYZ, pcl::PointXYZ> tfe;
00174   tfe.estimateRigidTransformation(src_pc_, dst_pc_, transform_);
00175   std::cout << "Transform : " << std::endl << transform_ << std::endl;
00176 }
00177 
00178 void
00179 ManualRegistration::clearPressed()
00180 {
00181   dst_point_selected_ = false;
00182   src_point_selected_ = false;
00183   src_pc_.points.clear();
00184   dst_pc_.points.clear();
00185   src_pc_.height = 1; src_pc_.width = 0;
00186   dst_pc_.height = 1; dst_pc_.width = 0;
00187 }
00188 
00189 void 
00190 ManualRegistration::orthoChanged (int state)
00191 {
00192   PCL_INFO ("Ortho state %d\n", state);
00193   if(state == 0) // Not selected
00194   {
00195     vis_src_->getRenderWindow ()->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->SetParallelProjection(0);
00196     vis_dst_->getRenderWindow ()->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->SetParallelProjection(0);
00197   }
00198   if(state == 2) // Selected
00199   {
00200     vis_src_->getRenderWindow ()->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->SetParallelProjection(1);
00201     vis_dst_->getRenderWindow ()->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->SetParallelProjection(1);
00202   }
00203   ui_->qvtk_widget_src->update();
00204   ui_->qvtk_widget_dst->update();
00205 }
00206 
00207 //TODO
00208 void 
00209 ManualRegistration::applyTransformPressed()
00210 {
00211 }
00212 
00213 void
00214 ManualRegistration::refinePressed()
00215 {
00216 }
00217 
00218 void
00219 ManualRegistration::undoPressed()
00220 {
00221 }
00222 
00223 void
00224 ManualRegistration::safePressed()
00225 {
00226 }
00227 
00228 void 
00229 ManualRegistration::timeoutSlot ()
00230 {
00231   if(cloud_src_present_ && cloud_src_modified_)
00232   {
00233     if(!vis_src_->updatePointCloud(cloud_src_, "cloud_src_"))
00234     {
00235       vis_src_->addPointCloud (cloud_src_, "cloud_src_");
00236       vis_src_->resetCameraViewpoint("cloud_src_");
00237     }
00238     cloud_src_modified_ = false;
00239   }
00240   if(cloud_dst_present_ && cloud_dst_modified_)
00241   {
00242     if(!vis_dst_->updatePointCloud(cloud_dst_, "cloud_dst_"))
00243     {
00244       vis_dst_->addPointCloud (cloud_dst_, "cloud_dst_");
00245       vis_dst_->resetCameraViewpoint("cloud_dst_");
00246     }
00247     cloud_dst_modified_ = false;
00248   }
00249   ui_->qvtk_widget_src->update();
00250   ui_->qvtk_widget_dst->update();
00251 }
00252 
00253 void
00254 print_usage ()
00255 {
00256   PCL_INFO ("manual_registration cloud1.pcd cloud2.pcd\n");
00257   PCL_INFO ("\t cloud1 \t source cloud\n");
00258   PCL_INFO ("\t cloud2 \t destination cloud\n");
00259 }
00260 
00261 int
00262 main (int argc, char** argv)
00263 {
00264   QApplication app(argc, argv);
00265 
00266   pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_src (new pcl::PointCloud<pcl::PointXYZRGBA>);
00267   pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_dst (new pcl::PointCloud<pcl::PointXYZRGBA>);
00268 
00269   if(argc < 3)
00270   {
00271     PCL_ERROR ("Incorrect usage\n");
00272     print_usage();
00273   }
00274 
00275   // TODO do this with PCL console
00276   if (pcl::io::loadPCDFile<pcl::PointXYZRGBA> (argv[1], *cloud_src) == -1) //* load the file
00277   {
00278     PCL_ERROR ("Couldn't read file %s \n", argv[1]);
00279     return (-1);
00280   }
00281   if (pcl::io::loadPCDFile<pcl::PointXYZRGBA> (argv[2], *cloud_dst) == -1) //* load the file
00282   {
00283     PCL_ERROR ("Couldn't read file %s \n", argv[2]);
00284     return (-1);
00285   }
00286 
00287   ManualRegistration man_reg;
00288 
00289   man_reg.setSrcCloud(cloud_src);
00290   man_reg.setDstCloud(cloud_dst);
00291 
00292   man_reg.show();
00293 
00294   return (app.exec());
00295 }


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