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