Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
registration.hpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id: registration.hpp 5044 2012-03-12 21:32:58Z rusu $
37  *
38  */
39 
41 template <typename PointSource, typename PointTarget> inline void
43 {
44  if (cloud->points.empty ())
45  {
46  PCL_ERROR ("[pcl::%s::setInputTarget] Invalid or empty point cloud dataset given!\n", getClassName ().c_str ());
47  return;
48  }
49  PointCloudTarget target = *cloud;
50  // Set all the point.data[3] values to 1 to aid the rigid transformation
51  for (size_t i = 0; i < target.points.size (); ++i)
52  target.points[i].data[3] = 1.0;
53 
54  //target_ = cloud;
55  target_ = target.makeShared ();
56  tree_->setInputCloud (target_);
57 }
58 
60 template <typename PointSource, typename PointTarget> inline double
61 pcl::Registration<PointSource, PointTarget>::getFitnessScore (const std::vector<float> &distances_a,
62  const std::vector<float> &distances_b)
63 {
64  unsigned int nr_elem = static_cast<unsigned int> (std::min (distances_a.size (), distances_b.size ()));
65  Eigen::VectorXf map_a = Eigen::VectorXf::Map (&distances_a[0], nr_elem);
66  Eigen::VectorXf map_b = Eigen::VectorXf::Map (&distances_b[0], nr_elem);
67  return (static_cast<double> ((map_a - map_b).sum ()) / static_cast<double> (nr_elem));
68 }
69 
71 template <typename PointSource, typename PointTarget> inline double
73 {
74  double fitness_score = 0.0;
75 
76  // Transform the input dataset using the final transformation
77  PointCloudSource input_transformed;
78  transformPointCloud (*input_, input_transformed, final_transformation_);
79 
80  std::vector<int> nn_indices (1);
81  std::vector<float> nn_dists (1);
82 
83  // For each point in the source dataset
84  int nr = 0;
85  for (size_t i = 0; i < input_transformed.points.size (); ++i)
86  {
87  Eigen::Vector4f p1 = Eigen::Vector4f (input_transformed.points[i].x,
88  input_transformed.points[i].y,
89  input_transformed.points[i].z, 0);
90  // Find its nearest neighbor in the target
91  tree_->nearestKSearch (input_transformed.points[i], 1, nn_indices, nn_dists);
92 
93  // Deal with occlusions (incomplete targets)
94  if (nn_dists[0] > max_range)
95  continue;
96 
97  Eigen::Vector4f p2 = Eigen::Vector4f (target_->points[nn_indices[0]].x,
98  target_->points[nn_indices[0]].y,
99  target_->points[nn_indices[0]].z, 0);
100  // Calculate the fitness score
101  fitness_score += fabs ((p1-p2).squaredNorm ());
102  nr++;
103  }
104 
105  if (nr > 0)
106  return (fitness_score / nr);
107  else
108  return (std::numeric_limits<double>::max ());
109 }
110 
112 template <typename PointSource, typename PointTarget> inline void
114 {
115  align (output, Eigen::Matrix4f::Identity());
116 }
117 
119 template <typename PointSource, typename PointTarget> inline void
121 {
122  if (!initCompute ()) return;
123 
124  if (!target_)
125  {
126  PCL_WARN ("[pcl::%s::compute] No input target dataset was given!\n", getClassName ().c_str ());
127  return;
128  }
129 
130  // Resize the output dataset
131  if (output.points.size () != indices_->size ())
132  output.points.resize (indices_->size ());
133  // Copy the header
134  output.header = input_->header;
135  // Check if the output will be computed for all points or only a subset
136  if (indices_->size () != input_->points.size ())
137  {
138  output.width = static_cast<uint32_t> (indices_->size ());
139  output.height = 1;
140  }
141  else
142  {
143  output.width = static_cast<uint32_t> (input_->width);
144  output.height = input_->height;
145  }
146  output.is_dense = input_->is_dense;
147 
148  // Copy the point data to output
149  for (size_t i = 0; i < indices_->size (); ++i)
150  output.points[i] = input_->points[(*indices_)[i]];
151 
152  // Set the internal point representation of choice
153  if (point_representation_)
154  tree_->setPointRepresentation (point_representation_);
155 
156  // Perform the actual transformation computation
157  converged_ = false;
158  final_transformation_ = transformation_ = previous_transformation_ = Eigen::Matrix4f::Identity ();
159 
160  // Right before we estimate the transformation, we set all the point.data[3] values to 1 to aid the rigid
161  // transformation
162  for (size_t i = 0; i < indices_->size (); ++i)
163  output.points[i].data[3] = 1.0;
164 
165  computeTransformation (output, guess);
166 
167  deinitCompute ();
168 }
169