Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
registration_visualizer.hpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2010, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage, Inc. nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * $Id: registration_visualizer.hpp 2011-07-15 00:18:54Z georgeLisca $
35  *
36  */
37 
39 template<typename PointSource, typename PointTarget> void
41  {
42  // Create and start the rendering thread. This will open the display window.
43  viewer_thread_ = boost::thread (&pcl::RegistrationVisualizer<PointSource, PointTarget>::runDisplay, this);
44  }
45 
47 template<typename PointSource, typename PointTarget> void
49  {
50  // Stop the rendering thread. This will kill the display window.
51  viewer_thread_.~thread ();
52  }
53 
55 template<typename PointSource, typename PointTarget> void
57  {
58  // Open 3D viewer
59  viewer_
60  = boost::shared_ptr<pcl::visualization::PCLVisualizer> (new pcl::visualization::PCLVisualizer ("3D Viewer"));
61  viewer_->initCameraParameters ();
62 
63  // Create the handlers for the three point clouds buffers: cloud_source_, cloud_target_ and cloud_intermediate_
64  pcl::visualization::PointCloudColorHandlerCustom<PointSource> cloud_source_handler_ (cloud_source_.makeShared (),
65  255, 0, 0);
66  pcl::visualization::PointCloudColorHandlerCustom<PointTarget> cloud_target_handler_ (cloud_target_.makeShared (),
67  0, 0, 255);
68  pcl::visualization::PointCloudColorHandlerCustom<PointSource> cloud_intermediate_handler_ (cloud_intermediate_.makeShared (),
69  255, 255, 0);
70 
71  // Create the view port for displaying initial source and target point clouds
72  int v1 (0);
73  viewer_->createViewPort (0.0, 0.0, 0.5, 1.0, v1);
74  viewer_->setBackgroundColor (0, 0, 0, v1);
75  viewer_->addText ("Initial position of source and target point clouds", 10, 50, "title v1", v1);
76  viewer_->addText ("Blue -> target", 10, 30, 0.0, 0.0, 1.0, "legend target v1", v1);
77  viewer_->addText ("Red -> source", 10, 10, 1.0, 0.0, 0.0, "legend source v1", v1);
78  //
79  viewer_->addPointCloud<PointSource> (cloud_source_.makeShared (), cloud_source_handler_, "cloud source v1", v1);
80  viewer_->addPointCloud<PointTarget> (cloud_target_.makeShared (), cloud_target_handler_, "cloud target v1", v1);
81 
82  // Create the view port for displaying the registration process of source to target point cloud
83  int v2 (0);
84  viewer_->createViewPort (0.5, 0.0, 1.0, 1.0, v2);
85  viewer_->setBackgroundColor (0.1, 0.1, 0.1, v2);
86  std::string registration_port_title_ = "Registration using "+registration_method_name_;
87  viewer_->addText (registration_port_title_, 10, 90, "title v2", v2);
88 
89  viewer_->addText ("Yellow -> intermediate", 10, 50, 1.0, 1.0, 0.0, "legend intermediate v2", v2);
90  viewer_->addText ("Blue -> target", 10, 30, 0.0, 0.0, 1.0, "legend target v2", v2);
91  viewer_->addText ("Red -> source", 10, 10, 1.0, 0.0, 0.0, "legend source v2", v1);
92 
93 // viewer_->addPointCloud<PointSource> (cloud_source_.makeShared (), cloud_source_handler_, "cloud source v2", v2);
94  viewer_->addPointCloud<PointTarget> (cloud_target_.makeShared (), cloud_target_handler_, "cloud target v2", v2);
95  viewer_->addPointCloud<PointSource> (cloud_intermediate_.makeShared (), cloud_intermediate_handler_,
96  "cloud intermediate v2", v2);
97 
98  // Used to remove all old correspondences
99  size_t correspondeces_old_size = 0;
100 
101  // Add coordinate system to both ports
102  viewer_->addCoordinateSystem (1.0);
103 
104  // The root name of correspondence lines
105  std::string line_root_ = "line";
106 
107  // Visualization loop
108  while (!viewer_->wasStopped ())
109  {
110  // Lock access to visualizer buffers
111  visualizer_updating_mutex_.lock ();
112 
113  // Updating intermediate point cloud
114  // Remove old point cloud
115  viewer_->removePointCloud ("cloud intermediate v2", v2);
116 
117  // Add the new point cloud
118  viewer_->addPointCloud<pcl::PointXYZ> (cloud_intermediate_.makeShared (), cloud_intermediate_handler_,
119  "cloud intermediate v2", v2);
120 
121  // Updating the correspondece lines
122 
123  std::string line_name_;
124  // Remove the old correspondeces
125  for (size_t correspondence_id = 0; correspondence_id < correspondeces_old_size; ++correspondence_id)
126  {
127  // Generate the line name
128  line_name_ = getIndexedName (line_root_, correspondence_id);
129 
130  // Remove the current line according to it's name
131  viewer_->removeShape (line_name_, v2);
132  }
133 
134  // Display the new correspondences lines
135  size_t correspondences_new_size = cloud_intermediate_indices_.size ();
136 
137 
138  std::stringstream stream_;
139  stream_ << "Random -> correspondences " << correspondences_new_size;
140  viewer_->removeShape ("correspondences_size", 0);
141  viewer_->addText (stream_.str(), 10, 70, 0.0, 1.0, 0.0, "correspondences_size", v2);
142 
143  // Display entire set of correspondece lines if no maximum displayed correspondences is set
144  if( ( 0 < maximum_displayed_correspondences_ ) &&
145  (maximum_displayed_correspondences_ < correspondences_new_size) )
146  correspondences_new_size = maximum_displayed_correspondences_;
147 
148  // Actualize correspondeces_old_size
149  correspondeces_old_size = correspondences_new_size;
150 
151  // Update new correspondence lines
152  for (size_t correspondence_id = 0; correspondence_id < correspondences_new_size; ++correspondence_id)
153  {
154  // Generate random color for current correspondence line
155  double random_red = 255 * rand () / (RAND_MAX + 1.0);
156  double random_green = 255 * rand () / (RAND_MAX + 1.0);
157  double random_blue = 255 * rand () / (RAND_MAX + 1.0);
158 
159  // Generate the name for current line
160  line_name_ = getIndexedName (line_root_, correspondence_id);
161 
162  // Add the new correspondence line.
163  viewer_->addLine (cloud_intermediate_[cloud_intermediate_indices_[correspondence_id]],
164  cloud_target_[cloud_target_indices_[correspondence_id]],
165  random_red, random_green, random_blue,
166  line_name_, v2);
167  }
168 
169  // Unlock access to visualizer buffers
170  visualizer_updating_mutex_.unlock ();
171 
172  // Render visualizer updated buffers
173  viewer_->spinOnce (100);
174  boost::this_thread::sleep (boost::posix_time::microseconds (100000));
175 
176  }
177  }
178 
180 template<typename PointSource, typename PointTarget> void
182  const pcl::PointCloud<PointSource> &cloud_src,
183  const std::vector<int> &indices_src,
184  const pcl::PointCloud<PointTarget> &cloud_tgt,
185  const std::vector<int> &indices_tgt)
186  {
187  // Lock local buffers
188  visualizer_updating_mutex_.lock ();
189 
190  // Update source and target point clouds if this is the first callback
191  // Here we are sure that source and target point clouds are initialized
192  if (!first_update_flag_)
193  {
194  first_update_flag_ = true;
195 
196  this->cloud_source_ = cloud_src;
197  this->cloud_target_ = cloud_tgt;
198 
199  this->cloud_intermediate_ = cloud_src;
200  }
201 
202  // Copy the intermediate point cloud and it's associates indices
203  cloud_intermediate_ = cloud_src;
204  cloud_intermediate_indices_ = indices_src;
205 
206  // Copy the intermediate indices associate to the target point cloud
207  cloud_target_indices_ = indices_tgt;
208 
209  // Unlock local buffers
210  visualizer_updating_mutex_.unlock ();
211  }