00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <pcl/apps/manual_registration.h>
00042
00043
00044 #include <QApplication>
00045 #include <QMutexLocker>
00046 #include <QEvent>
00047 #include <QObject>
00048
00049
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
00061 vis_timer_ = new QTimer (this);
00062 vis_timer_->start (5);
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
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
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
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;
00102 cloud_dst_modified_ = true;
00103 }
00104
00105 void
00106 ManualRegistration::SourcePointPickCallback (const pcl::visualization::PointPickingEvent& event, void*)
00107 {
00108
00109 int idx = event.getPointIndex ();
00110 if (idx == -1)
00111 return;
00112
00113
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
00123 int idx = event.getPointIndex ();
00124 if (idx == -1)
00125 return;
00126
00127
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)
00194 {
00195 vis_src_->getRenderWindow ()->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->SetParallelProjection(0);
00196 vis_dst_->getRenderWindow ()->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->SetParallelProjection(0);
00197 }
00198 if(state == 2)
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
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
00276 if (pcl::io::loadPCDFile<pcl::PointXYZRGBA> (argv[1], *cloud_src) == -1)
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)
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 }