367 lines
14 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The PCL Registration API &mdash; Point Cloud Library 1.12.0 documentation</title>
<script type="text/javascript" src="_static/js/modernizr.min.js"></script>
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Point Cloud Library
</a>
<div class="version">
1.12.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<!-- Local TOC -->
<div class="local-toc"><ul>
<li><a class="reference internal" href="#">The PCL Registration API</a></li>
<li><a class="reference internal" href="#an-overview-of-pairwise-registration">An overview of pairwise registration</a></li>
<li><a class="reference internal" href="#registration-modules">Registration modules</a><ul>
<li><a class="reference internal" href="#keypoints">Keypoints</a></li>
<li><a class="reference internal" href="#feature-descriptors">Feature descriptors</a></li>
<li><a class="reference internal" href="#correspondences-estimation">Correspondences estimation</a></li>
<li><a class="reference internal" href="#correspondences-rejection">Correspondences rejection</a></li>
<li><a class="reference internal" href="#transformation-estimation">Transformation estimation</a></li>
<li><a class="reference internal" href="#example-pipelines">Example pipelines</a><ul>
<li><a class="reference internal" href="#iterative-closest-point">Iterative Closest Point</a></li>
<li><a class="reference internal" href="#feature-based-registration">Feature based registration</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#example-1-office-scene-kinect-data">Example 1: Office scene, Kinect data</a></li>
<li><a class="reference internal" href="#example-2-outdoor-scene-laser-riegl-data">Example 2: Outdoor scene, Laser (Riegl) data</a></li>
<li><a class="reference internal" href="#example-3-indoor-scene-laser-sick-data">Example 3: Indoor scene, Laser (SICK) data</a></li>
</ul>
</div>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Point Cloud Library</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html">Docs</a> &raquo;</li>
<li>The PCL Registration API</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="the-pcl-registration-api">
<span id="registration-api"></span><h1>The PCL Registration API</h1>
<p>The problem of consistently aligning various 3D point cloud data views into a
complete model is known as <strong>registration</strong>. Its goal is to find the relative
positions and orientations of the separately acquired views in a global
coordinate framework, such that the intersecting areas between them overlap
perfectly. For every set of point cloud datasets acquired from different views,
we therefore need a system that is able to align them together into a single
point cloud model, so that subsequent processing steps such as segmentation and
object reconstruction can be applied.</p>
<img alt="_images/scans.jpg" class="align-center" src="_images/scans.jpg" />
<p>A motivation example in this sense is given in the figure above, where a set of
six individual datasets has been acquired using a tilting 2D laser unit. Since
each individual scan represents only a small part of the surrounding world, it
is imperative to find ways to register them together, thus creating the complete
point cloud model as shown in the figure below.</p>
<img alt="_images/s1-6.jpg" class="align-center" src="_images/s1-6.jpg" />
<p>The algorithmic work in the PCL registration library is motivated by finding
correct point correspondences in the given input datasets, and estimating rigid
transformations that can rotate and translate each individual dataset into a
consistent global coordinate framework. This registration paradigm becomes
easily solvable if the point correspondences are perfectly known in the input
datasets. This means that a selected list of points in one dataset have to
“coincide” from a feature representation point of view with a list of points
from another dataset. Additionally, if the correspondences estimated are
“perfect”, then the registration problem has a closed form solution.</p>
<p>PCL contains a set of powerful algorithms that allow the estimation of multiple
sets of correspondences, as well as methods for rejecting bad correspondences,
and estimating transformations in a robust manner from them. The following
sections will describe each of them individually.</p>
</div>
<div class="section" id="an-overview-of-pairwise-registration">
<h1>An overview of pairwise registration</h1>
<p>We sometimes refer to the problem of registering a pair of point cloud datasets
together as <em>pairwise registration</em>, and its output is usually a rigid
transformation matrix (4x4) representing the rotation and translation that would
have to be applied on one of the datasets (lets call it <em>source</em>) in order for
it to be perfectly aligned with the other dataset (lets call it <em>target</em>, or
<em>model</em>).</p>
<p>The steps performed in a <em>pairwise registration</em> step are shown in the diagram
below. Please note that we are representing a single iteration of the algorithm.
The programmer can decide to loop over any or all of the steps.</p>
<img alt="_images/block_diagram_single_iteration.jpg" class="align-center" src="_images/block_diagram_single_iteration.jpg" />
<p>The computational steps for two datasets are straightforward:</p>
<blockquote>
<div><ul class="simple">
<li>from a set of points, identify <strong>interest points</strong> (i.e., <strong>keypoints</strong>) that best represent the scene in both datasets;</li>
<li>at each keypoint, compute a <strong>feature descriptor</strong>;</li>
<li>from the set of <strong>feature descriptors</strong> together with their XYZ positions in the two datasets, estimate a set of <strong>correspondences</strong>, based on the similarities between features and positions;</li>
<li>given that the data is assumed to be noisy, not all correspondences are valid, so reject those bad correspondences that contribute negatively to the registration process;</li>
<li>from the remaining set of good correspondences, estimate a motion transformation.</li>
</ul>
</div></blockquote>
</div>
<div class="section" id="registration-modules">
<h1>Registration modules</h1>
<p>Lets have a look at the single steps of the pipeline.</p>
<div class="section" id="keypoints">
<h2>Keypoints</h2>
<p>A keypoint is an interest point that has a “special property” in the scene,
like the corner of a book, or the letter “P” on a book that has written “PCL”
on it. There are a number of different keypoints available in PCL like NARF,
SIFT and FAST. Alternatively you can take every point, or a subset, as
keypoints as well. The problem with “feeding two kinect datasets into a correspondence estimation” directly is that you have 300k points in each frame, so there can be 300k^2 correspondences.</p>
</div>
<div class="section" id="feature-descriptors">
<h2>Feature descriptors</h2>
<p>Based on the keypoints found we have to extract [features](<a class="reference external" href="http://www.pointclouds.org/documentation/tutorials/how_features_work.php">http://www.pointclouds.org/documentation/tutorials/how_features_work.php</a>), where we assemble the information and generate vectors to compare them with each other. Again there
is a number of feature options to choose from, for example NARF, FPFH, BRIEF or
SIFT.</p>
</div>
<div class="section" id="correspondences-estimation">
<h2>Correspondences estimation</h2>
<p>Given two sets of feature vectors coming from two acquired scans we have to
find corresponding features to find overlapping parts in the data. Depending on
the feature type we can use different methods to find the correspondences.</p>
<p>For <em>point matching</em> (using the points xyz-coordinates as features) different
methods exist for organized and unorganized data:</p>
<ul class="simple">
<li>brute force matching,</li>
<li>kd-tree nearest neighbor search (FLANN),</li>
<li>searching in the image space of organized data, and</li>
<li>searching in the index space of organized data.</li>
</ul>
<p>For <em>feature matching</em> (not using the points coordinates, but certain features)
only the following methods exist:</p>
<ul class="simple">
<li>brute force matching and</li>
<li>kd-tree nearest neighbor search (FLANN).</li>
</ul>
<p>In addition to the search, two types of correspondence estimation are
distinguished:</p>
<ul class="simple">
<li>Direct correspondence estimation (default) searches for correspondences
in cloud B for every point in cloud A .</li>
<li>“Reciprocal” correspondence estimation searches for correspondences from
cloud A to cloud B, and from B to A and only use the intersection.</li>
</ul>
</div>
<div class="section" id="correspondences-rejection">
<h2>Correspondences rejection</h2>
<p>Naturally, not all estimated correspondences are correct.
Since wrong correspondences can negatively affect the estimation of the final
transformation, they need to be rejected.
This could be done using RANSAC or by trimming down the amount and using only a
certain percent of the found correspondences.</p>
<p>A special case are one to many correspondences where one point in the model
corresponds to a number of points in the source. These could be filtered by
using only the one with the smallest distance or by checking for other
matchings near by.</p>
</div>
<div class="section" id="transformation-estimation">
<h2>Transformation estimation</h2>
<p>The last step is to actually compute the transformation.</p>
<ul class="simple">
<li>evaluate some error metric based on correspondence</li>
<li>estimate a (rigid) transformation between camera poses (motion estimate) and minimize error metric</li>
<li>optimize the structure of the points</li>
<li>Examples:
- SVD for motion estimate;
- Levenberg-Marquardt with different kernels for motion estimate;</li>
<li>use the rigid transformation to rotate/translate the source onto the target,
and potentially run an internal ICP loop with either all points or a subset
of points or the keypoints</li>
<li>iterate until some convergence criterion is met</li>
</ul>
</div>
<div class="section" id="example-pipelines">
<h2>Example pipelines</h2>
<div class="section" id="iterative-closest-point">
<h3>Iterative Closest Point</h3>
<ol class="arabic simple">
<li>Search for correspondences.</li>
<li>Reject bad correspondences.</li>
<li>Estimate a transformation using the good correspondences.</li>
<li>Iterate.</li>
</ol>
</div>
<div class="section" id="feature-based-registration">
<h3>Feature based registration</h3>
<ol class="arabic simple">
<li>use SIFT Keypoints (pcl::SIFT…something)</li>
<li>use FPFH descriptors (pcl::FPFHEstimation) at the keypoints (see our tutorials for that, like http://www.pointclouds.org/media/rss2011.html)</li>
<li>get the FPFH descriptors and estimate correspondences using pcl::CorrespondenceEstimation</li>
<li>reject bad correspondences using one or many of the pcl::CorrespondenceRejectionXXX methods</li>
<li>finally get a transformation as mentioned above</li>
</ol>
</div>
</div>
</div>
<div class="section" id="example-1-office-scene-kinect-data">
<h1>Example 1: Office scene, Kinect data</h1>
</div>
<div class="section" id="example-2-outdoor-scene-laser-riegl-data">
<h1>Example 2: Outdoor scene, Laser (Riegl) data</h1>
</div>
<div class="section" id="example-3-indoor-scene-laser-sick-data">
<h1>Example 3: Indoor scene, Laser (SICK) data</h1>
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>