Point Cloud Library (PCL) 1.15.1-dev
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.
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
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.
RegistrationVisualizer represents the base class for rendering the intermediate positions occupied by...
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