123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- //
- // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
- //
- // By downloading, copying, installing or using the software you agree to this license.
- // If you do not agree to this license, do not download, install,
- // copy or use the software.
- //
- //
- // License Agreement
- // For Open Source Computer Vision Library
- //
- // Copyright (C) 2014, OpenCV Foundation, all rights reserved.
- // Third party copyrights are property of their respective owners.
- //
- // Redistribution and use in source and binary forms, with or without modification,
- // are permitted provided that the following conditions are met:
- //
- // * Redistribution's of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- //
- // * Redistribution's in binary form must reproduce the above copyright notice,
- // this list of conditions and the following disclaimer in the documentation
- // and/or other materials provided with the distribution.
- //
- // * The name of the copyright holders may not be used to endorse or promote products
- // derived from this software without specific prior written permission.
- //
- // This software is provided by the copyright holders and contributors "as is" and
- // any express or implied warranties, including, but not limited to, the implied
- // warranties of merchantability and fitness for a particular purpose are disclaimed.
- // In no event shall the Intel Corporation or contributors be liable for any direct,
- // indirect, incidental, special, exemplary, or consequential damages
- // (including, but not limited to, procurement of substitute goods or services;
- // loss of use, data, or profits; or business interruption) however caused
- // and on any theory of liability, whether in contract, strict liability,
- // or tort (including negligence or otherwise) arising in any way out of
- // the use of this software, even if advised of the possibility of such damage.
- #ifndef __OPENCV_SURFACE_MATCHING_HPP__
- #define __OPENCV_SURFACE_MATCHING_HPP__
- #include "surface_matching/ppf_match_3d.hpp"
- #include "surface_matching/icp.hpp"
- /** @defgroup surface_matching Surface Matching
- Note about the License and Patents
- -----------------------------------
- The following patents have been issued for methods embodied in this
- software: "Recognition and pose determination of 3D objects in 3D scenes
- using geometric point pair descriptors and the generalized Hough
- Transform", Bertram Heinrich Drost, Markus Ulrich, EP Patent 2385483
- (Nov. 21, 2012), assignee: MVTec Software GmbH, 81675 Muenchen
- (Germany); "Recognition and pose determination of 3D objects in 3D
- scenes", Bertram Heinrich Drost, Markus Ulrich, US Patent 8830229 (Sept.
- 9, 2014), assignee: MVTec Software GmbH, 81675 Muenchen (Germany).
- Further patents are pending. For further details, contact MVTec Software
- GmbH (info@mvtec.com).
- Note that restrictions imposed by these patents (and possibly others)
- exist independently of and may be in conflict with the freedoms granted
- in this license, which refers to copyright of the program, not patents
- for any methods that it implements. Both copyright and patent law must
- be obeyed to legally use and redistribute this program and it is not the
- purpose of this license to induce you to infringe any patents or other
- property right claims or to contest validity of any such claims. If you
- redistribute or use the program, then this license merely protects you
- from committing copyright infringement. It does not protect you from
- committing patent infringement. So, before you do anything with this
- program, make sure that you have permission to do so not merely in terms
- of copyright, but also in terms of patent law.
- Please note that this license is not to be understood as a guarantee
- either. If you use the program according to this license, but in
- conflict with patent law, it does not mean that the licensor will refund
- you for any losses that you incur if you are sued for your patent
- infringement.
- Introduction to Surface Matching
- --------------------------------
- Cameras and similar devices with the capability of sensation of 3D structure are becoming more
- common. Thus, using depth and intensity information for matching 3D objects (or parts) are of
- crucial importance for computer vision. Applications range from industrial control to guiding
- everyday actions for visually impaired people. The task in recognition and pose estimation in range
- images aims to identify and localize a queried 3D free-form object by matching it to the acquired
- database.
- From an industrial perspective, enabling robots to automatically locate and pick up randomly placed
- and oriented objects from a bin is an important challenge in factory automation, replacing tedious
- and heavy manual labor. A system should be able to recognize and locate objects with a predefined
- shape and estimate the position with the precision necessary for a gripping robot to pick it up.
- This is where vision guided robotics takes the stage. Similar tools are also capable of guiding
- robots (and even people) through unstructured environments, leading to automated navigation. These
- properties make 3D matching from point clouds a ubiquitous necessity. Within this context, I will
- now describe the OpenCV implementation of a 3D object recognition and pose estimation algorithm
- using 3D features.
- Surface Matching Algorithm Through 3D Features
- ----------------------------------------------
- The state of the algorithms in order to achieve the task 3D matching is heavily based on
- @cite drost2010, which is one of the first and main practical methods presented in this area. The
- approach is composed of extracting 3D feature points randomly from depth images or generic point
- clouds, indexing them and later in runtime querying them efficiently. Only the 3D structure is
- considered, and a trivial hash table is used for feature queries.
- While being fully aware that utilization of the nice CAD model structure in order to achieve a smart
- point sampling, I will be leaving that aside now in order to respect the generalizability of the
- methods (Typically for such algorithms training on a CAD model is not needed, and a point cloud
- would be sufficient). Below is the outline of the entire algorithm:
- 
- As explained, the algorithm relies on the extraction and indexing of point pair features, which are
- defined as follows:
- \f[\bf{{F}}(\bf{{m1}}, \bf{{m2}}) = (||\bf{{d}}||_2, <(\bf{{n1}},\bf{{d}}), <(\bf{{n2}},\bf{{d}}), <(\bf{{n1}},\bf{{n2}}))\f]
- where \f$\bf{{m1}}\f$ and \f$\bf{{m2}}\f$ are feature two selected points on the model (or scene),
- \f$\bf{{d}}\f$ is the difference vector, \f$\bf{{n1}}\f$ and \f$\bf{{n2}}\f$ are the normals at \f$\bf{{m1}}\f$ and
- \f$\bf{m2}\f$. During the training stage, this vector is quantized, indexed. In the test stage, same
- features are extracted from the scene and compared to the database. With a few tricks like
- separation of the rotational components, the pose estimation part can also be made efficient (check
- the reference for more details). A Hough-like voting and clustering is employed to estimate the
- object pose. To cluster the poses, the raw pose hypotheses are sorted in decreasing order of the
- number of votes. From the highest vote, a new cluster is created. If the next pose hypothesis is
- close to one of the existing clusters, the hypothesis is added to the cluster and the cluster center
- is updated as the average of the pose hypotheses within the cluster. If the next hypothesis is not
- close to any of the clusters, it creates a new cluster. The proximity testing is done with fixed
- thresholds in translation and rotation. Distance computation and averaging for translation are
- performed in the 3D Euclidean space, while those for rotation are performed using quaternion
- representation. After clustering, the clusters are sorted in decreasing order of the total number of
- votes which determines confidence of the estimated poses.
- This pose is further refined using \f$ICP\f$ in order to obtain the final pose.
- PPF presented above depends largely on robust computation of angles between 3D vectors. Even though
- not reported in the paper, the naive way of doing this (\f$\theta = cos^{-1}({\bf{a}}\cdot{\bf{b}})\f$
- remains numerically unstable. A better way to do this is then use inverse tangents, like:
- \f[<(\bf{n1},\bf{n2})=tan^{-1}(||{\bf{n1} \wedge \bf{n2}}||_2, \bf{n1} \cdot \bf{n2})\f]
- Rough Computation of Object Pose Given PPF
- ------------------------------------------
- Let me summarize the following notation:
- - \f$p^i_m\f$: \f$i^{th}\f$ point of the model (\f$p^j_m\f$ accordingly)
- - \f$n^i_m\f$: Normal of the \f$i^{th}\f$ point of the model (\f$n^j_m\f$ accordingly)
- - \f$p^i_s\f$: \f$i^{th}\f$ point of the scene (\f$p^j_s\f$ accordingly)
- - \f$n^i_s\f$: Normal of the \f$i^{th}\f$ point of the scene (\f$n^j_s\f$ accordingly)
- - \f$T_{m\rightarrow g}\f$: The transformation required to translate \f$p^i_m\f$ to the origin and rotate
- its normal \f$n^i_m\f$ onto the \f$x\f$-axis.
- - \f$R_{m\rightarrow g}\f$: Rotational component of \f$T_{m\rightarrow g}\f$.
- - \f$t_{m\rightarrow g}\f$: Translational component of \f$T_{m\rightarrow g}\f$.
- - \f$(p^i_m)^{'}\f$: \f$i^{th}\f$ point of the model transformed by \f$T_{m\rightarrow g}\f$. (\f$(p^j_m)^{'}\f$
- accordingly).
- - \f${\bf{R_{m\rightarrow g}}}\f$: Axis angle representation of rotation \f$R_{m\rightarrow g}\f$.
- - \f$\theta_{m\rightarrow g}\f$: The angular component of the axis angle representation
- \f${\bf{R_{m\rightarrow g}}}\f$.
- The transformation in a point pair feature is computed by first finding the transformation
- \f$T_{m\rightarrow g}\f$ from the first point, and applying the same transformation to the second one.
- Transforming each point, together with the normal, to the ground plane leaves us with an angle to
- find out, during a comparison with a new point pair.
- We could now simply start writing
- \f[(p^i_m)^{'} = T_{m\rightarrow g} p^i_m\f]
- where
- \f[T_{m\rightarrow g} = -t_{m\rightarrow g}R_{m\rightarrow g}\f]
- Note that this is nothing but a stacked transformation. The translational component
- \f$t_{m\rightarrow g}\f$ reads
- \f[t_{m\rightarrow g} = -R_{m\rightarrow g}p^i_m\f]
- and the rotational being
- \f[\theta_{m\rightarrow g} = \cos^{-1}(n^i_m \cdot {\bf{x}})\\
- {\bf{R_{m\rightarrow g}}} = n^i_m \wedge {\bf{x}}\f]
- in axis angle format. Note that bold refers to the vector form. After this transformation, the
- feature vectors of the model are registered onto the ground plane X and the angle with respect to
- \f$x=0\f$ is called \f$\alpha_m\f$. Similarly, for the scene, it is called \f$\alpha_s\f$.
- ### Hough-like Voting Scheme
- As shown in the outline, PPF (point pair features) are extracted from the model, quantized, stored
- in the hashtable and indexed, during the training stage. During the runtime however, the similar
- operation is perfomed on the input scene with the exception that this time a similarity lookup over
- the hashtable is performed, instead of an insertion. This lookup also allows us to compute a
- transformation to the ground plane for the scene pairs. After this point, computing the rotational
- component of the pose reduces to computation of the difference \f$\alpha=\alpha_m-\alpha_s\f$. This
- component carries the cue about the object pose. A Hough-like voting scheme is performed over the
- local model coordinate vector and \f$\alpha\f$. The highest poses achieved for every scene point lets us
- recover the object pose.
- ### Source Code for PPF Matching
- ~~~{cpp}
- // pc is the loaded point cloud of the model
- // (Nx6) and pcTest is a loaded point cloud of
- // the scene (Mx6)
- ppf_match_3d::PPF3DDetector detector(0.03, 0.05);
- detector.trainModel(pc);
- vector<Pose3DPtr> results;
- detector.match(pcTest, results, 1.0/10.0, 0.05);
- cout << "Poses: " << endl;
- // print the poses
- for (size_t i=0; i<results.size(); i++)
- {
- Pose3DPtr pose = results[i];
- cout << "Pose Result " << i << endl;
- pose->printPose();
- }
- ~~~
- Pose Registration via ICP
- -------------------------
- The matching process terminates with the attainment of the pose. However, due to the multiple
- matching points, erroneous hypothesis, pose averaging and etc. such pose is very open to noise and
- many times is far from being perfect. Although the visual results obtained in that stage are
- pleasing, the quantitative evaluation shows \f$~10\f$ degrees variation (error), which is an acceptable
- level of matching. Many times, the requirement might be set well beyond this margin and it is
- desired to refine the computed pose.
- Furthermore, in typical RGBD scenes and point clouds, 3D structure can capture only less than half
- of the model due to the visibility in the scene. Therefore, a robust pose refinement algorithm,
- which can register occluded and partially visible shapes quickly and correctly is not an unrealistic
- wish.
- At this point, a trivial option would be to use the well known iterative closest point algorithm .
- However, utilization of the basic ICP leads to slow convergence, bad registration, outlier
- sensitivity and failure to register partial shapes. Thus, it is definitely not suited to the
- problem. For this reason, many variants have been proposed . Different variants contribute to
- different stages of the pose estimation process.
- ICP is composed of \f$6\f$ stages and the improvements I propose for each stage is summarized below.
- ### Sampling
- To improve convergence speed and computation time, it is common to use less points than the model
- actually has. However, sampling the correct points to register is an issue in itself. The naive way
- would be to sample uniformly and hope to get a reasonable subset. More smarter ways try to identify
- the critical points, which are found to highly contribute to the registration process. Gelfand et.
- al. exploit the covariance matrix in order to constrain the eigenspace, so that a set of points
- which affect both translation and rotation are used. This is a clever way of subsampling, which I
- will optionally be using in the implementation.
- ### Correspondence Search
- As the name implies, this step is actually the assignment of the points in the data and the model in
- a closest point fashion. Correct assignments will lead to a correct pose, where wrong assignments
- strongly degrade the result. In general, KD-trees are used in the search of nearest neighbors, to
- increase the speed. However this is not an optimality guarantee and many times causes wrong points
- to be matched. Luckily the assignments are corrected over iterations.
- To overcome some of the limitations, Picky ICP @cite pickyicp and BC-ICP (ICP using bi-unique
- correspondences) are two well-known methods. Picky ICP first finds the correspondences in the
- old-fashioned way and then among the resulting corresponding pairs, if more than one scene point
- \f$p_i\f$ is assigned to the same model point \f$m_j\f$, it selects \f$p_i\f$ that corresponds to the minimum
- distance. BC-ICP on the other hand, allows multiple correspondences first and then resolves the
- assignments by establishing bi-unique correspondences. It also defines a novel no-correspondence
- outlier, which intrinsically eases the process of identifying outliers.
- For reference, both methods are used. Because P-ICP is a bit faster, with not-so-significant
- performance drawback, it will be the method of choice in refinment of correspondences.
- ### Weighting of Pairs
- In my implementation, I currently do not use a weighting scheme. But the common approaches involve
- *normal compatibility* (\f$w_i=n^1_i\cdot n^2_j\f$) or assigning lower weights to point pairs with
- greater distances (\f$w=1-\frac{||dist(m_i,s_i)||_2}{dist_{max}}\f$).
- ### Rejection of Pairs
- The rejections are done using a dynamic thresholding based on a robust estimate of the standard
- deviation. In other words, in each iteration, I find the MAD estimate of the Std. Dev. I denote this
- as \f$mad_i\f$. I reject the pairs with distances \f$d_i>\tau mad_i\f$. Here \f$\tau\f$ is the threshold of
- rejection and by default set to \f$3\f$. The weighting is applied prior to Picky refinement, explained
- in the previous stage.
- ### Error Metric
- As described in , a linearization of point to plane as in @cite koklimlow error metric is used. This
- both speeds up the registration process and improves convergence.
- ### Minimization
- Even though many non-linear optimizers (such as Levenberg Mardquardt) are proposed, due to the
- linearization in the previous step, pose estimation reduces to solving a linear system of equations.
- This is what I do exactly using cv::solve with DECOMP_SVD option.
- ### ICP Algorithm
- Having described the steps above, here I summarize the layout of the ICP algorithm.
- #### Efficient ICP Through Point Cloud Pyramids
- While the up-to-now-proposed variants deal well with some outliers and bad initializations, they
- require significant number of iterations. Yet, multi-resolution scheme can help reducing the number
- of iterations by allowing the registration to start from a coarse level and propagate to the lower
- and finer levels. Such approach both improves the performances and enhances the runtime.
- The search is done through multiple levels, in a hierarchical fashion. The registration starts with
- a very coarse set of samples of the model. Iteratively, the points are densified and sought. After
- each iteration the previously estimated pose is used as an initial pose and refined with the ICP.
- #### Visual Results
- ##### Results on Synthetic Data
- In all of the results, the pose is initiated by PPF and the rest is left as:
- \f$[\theta_x, \theta_y, \theta_z, t_x, t_y, t_z]=[0]\f$
- ### Source Code for Pose Refinement Using ICP
- ~~~{cpp}
- ICP icp(200, 0.001f, 2.5f, 8);
- // Using the previously declared pc and pcTest
- // This will perform registration for every pose
- // contained in results
- icp.registerModelToScene(pc, pcTest, results);
- // results now contain the refined poses
- ~~~
- Results
- -------
- This section is dedicated to the results of surface matching (point-pair-feature matching and a
- following ICP refinement):
- 
- Matches of different models for Mian dataset is presented below:
- 
- You might checkout the video on [youTube here](http://www.youtube.com/watch?v=uFnqLFznuZU).
- A Complete Sample
- -----------------
- ### Parameter Tuning
- Surface matching module treats its parameters relative to the model diameter (diameter of the axis
- parallel bounding box), whenever it can. This makes the parameters independent from the model size.
- This is why, both model and scene cloud were subsampled such that all points have a minimum distance
- of \f$RelativeSamplingStep*DimensionRange\f$, where \f$DimensionRange\f$ is the distance along a given
- dimension. All three dimensions are sampled in similar manner. For example, if
- \f$RelativeSamplingStep\f$ is set to 0.05 and the diameter of model is 1m (1000mm), the points sampled
- from the object's surface will be approximately 50 mm apart. From another point of view, if the
- sampling RelativeSamplingStep is set to 0.05, at most \f$20x20x20 = 8000\f$ model points are generated
- (depending on how the model fills in the volume). Consequently this results in at most 8000x8000
- pairs. In practice, because the models are not uniformly distributed over a rectangular prism, much
- less points are to be expected. Decreasing this value, results in more model points and thus a more
- accurate representation. However, note that number of point pair features to be computed is now
- quadratically increased as the complexity is O(N\^2). This is especially a concern for 32 bit
- systems, where large models can easily overshoot the available memory. Typically, values in the
- range of 0.025 - 0.05 seem adequate for most of the applications, where the default value is 0.03.
- (Note that there is a difference in this paremeter with the one presented in @cite drost2010 . In
- @cite drost2010 a uniform cuboid is used for quantization and model diameter is used for reference of
- sampling. In my implementation, the cuboid is a rectangular prism, and each dimension is quantized
- independently. I do not take reference from the diameter but along the individual dimensions.
- It would very wise to remove the outliers from the model and prepare an ideal model initially. This
- is because, the outliers directly affect the relative computations and degrade the matching
- accuracy.
- During runtime stage, the scene is again sampled by \f$RelativeSamplingStep\f$, as described above.
- However this time, only a portion of the scene points are used as reference. This portion is
- controlled by the parameter \f$RelativeSceneSampleStep\f$, where
- \f$SceneSampleStep = (int)(1.0/RelativeSceneSampleStep)\f$. In other words, if the
- \f$RelativeSceneSampleStep = 1.0/5.0\f$, the subsampled scene will once again be uniformly sampled to
- 1/5 of the number of points. Maximum value of this parameter is 1 and increasing this parameter also
- increases the stability, but decreases the speed. Again, because of the initial scene-independent
- relative sampling, fine tuning this parameter is not a big concern. This would only be an issue when
- the model shape occupies a volume uniformly, or when the model shape is condensed in a tiny place
- within the quantization volume (e.g. The octree representation would have too much empty cells).
- \f$RelativeDistanceStep\f$ acts as a step of discretization over the hash table. The point pair features
- are quantized to be mapped to the buckets of the hashtable. This discretization involves a
- multiplication and a casting to the integer. Adjusting RelativeDistanceStep in theory controls the
- collision rate. Note that, more collisions on the hashtable results in less accurate estimations.
- Reducing this parameter increases the affect of quantization but starts to assign non-similar point
- pairs to the same bins. Increasing it however, wanes the ability to group the similar pairs.
- Generally, because during the sampling stage, the training model points are selected uniformly with
- a distance controlled by RelativeSamplingStep, RelativeDistanceStep is expected to equate to this
- value. Yet again, values in the range of 0.025-0.05 are sensible. This time however, when the model
- is dense, it is not advised to decrease this value. For noisy scenes, the value can be increased to
- improve the robustness of the matching against noisy points.
- */
- #endif
|