Skip to content

Commit b41783a

Browse files
committed
Merge pull request #70 from tolgabirdal/add_surface_matching_gsoc
Add surface_matching module.
2 parents 80da2ce + 8031741 commit b41783a

27 files changed

+775191
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
set(the_description "3D point features")
2+
ocv_define_module(surface_matching opencv_core opencv_flann)

modules/surface_matching/doc/surface_matching.rst

Lines changed: 355 additions & 0 deletions
Large diffs are not rendered by default.
107 KB
Loading
84.9 KB
Loading
109 KB
Loading
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//
2+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
3+
//
4+
// By downloading, copying, installing or using the software you agree to this license.
5+
// If you do not agree to this license, do not download, install,
6+
// copy or use the software.
7+
//
8+
//
9+
// License Agreement
10+
// For Open Source Computer Vision Library
11+
//
12+
// Copyright (C) 2014, OpenCV Foundation, all rights reserved.
13+
// Third party copyrights are property of their respective owners.
14+
//
15+
// Redistribution and use in source and binary forms, with or without modification,
16+
// are permitted provided that the following conditions are met:
17+
//
18+
// * Redistribution's of source code must retain the above copyright notice,
19+
// this list of conditions and the following disclaimer.
20+
//
21+
// * Redistribution's in binary form must reproduce the above copyright notice,
22+
// this list of conditions and the following disclaimer in the documentation
23+
// and/or other materials provided with the distribution.
24+
//
25+
// * The name of the copyright holders may not be used to endorse or promote products
26+
// derived from this software without specific prior written permission.
27+
//
28+
// This software is provided by the copyright holders and contributors "as is" and
29+
// any express or implied warranties, including, but not limited to, the implied
30+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
31+
// In no event shall the Intel Corporation or contributors be liable for any direct,
32+
// indirect, incidental, special, exemplary, or consequential damages
33+
// (including, but not limited to, procurement of substitute goods or services;
34+
// loss of use, data, or profits; or business interruption) however caused
35+
// and on any theory of liability, whether in contract, strict liability,
36+
// or tort (including negligence or otherwise) arising in any way out of
37+
// the use of this software, even if advised of the possibility of such damage.
38+
//
39+
// Author: Tolga Birdal <tbirdal AT gmail.com>
40+
41+
#include "opencv2/surface_matching.hpp"
42+
#include <iostream>
43+
#include "opencv2/surface_matching/ppf_helpers.hpp"
44+
#include "opencv2/core/utility.hpp"
45+
46+
using namespace std;
47+
using namespace cv;
48+
using namespace ppf_match_3d;
49+
50+
static void help(const string& errorMessage)
51+
{
52+
cout << "Program init error : "<< errorMessage << endl;
53+
cout << "\nUsage : ppf_matching [input model file] [input scene file]"<< endl;
54+
cout << "\nPlease start again with new parameters"<< endl;
55+
}
56+
57+
int main(int argc, char** argv)
58+
{
59+
// welcome message
60+
cout << "****************************************************" << endl;
61+
cout << "* Surface Matching demonstration : demonstrates the use of surface matching"
62+
" using point pair features." << endl;
63+
cout << "* The sample loads a model and a scene, where the model lies in a different"
64+
" pose than the training.\n* It then trains the model and searches for it in the"
65+
" input scene. The detected poses are further refined by ICP\n* and printed to the "
66+
" standard output." << endl;
67+
cout << "****************************************************" << endl;
68+
69+
if (argc < 3)
70+
{
71+
help("Not enough input arguments");
72+
exit(1);
73+
}
74+
75+
#if (defined __x86_64__ || defined _M_X64)
76+
cout << "Running on 64 bits" << endl;
77+
#else
78+
cout << "Running on 32 bits" << endl;
79+
#endif
80+
81+
#ifdef _OPENMP
82+
cout << "Running with OpenMP" << endl;
83+
#else
84+
cout << "Running without OpenMP and without TBB" << endl;
85+
#endif
86+
87+
string modelFileName = (string)argv[1];
88+
string sceneFileName = (string)argv[2];
89+
90+
Mat pc = loadPLYSimple(modelFileName.c_str(), 1);
91+
92+
// Now train the model
93+
cout << "Training..." << endl;
94+
int64 tick1 = cv::getTickCount();
95+
ppf_match_3d::PPF3DDetector detector(0.025, 0.05);
96+
detector.trainModel(pc);
97+
int64 tick2 = cv::getTickCount();
98+
cout << endl << "Training complete in "
99+
<< (double)(tick2-tick1)/ cv::getTickFrequency()
100+
<< " sec" << endl << "Loading model..." << endl;
101+
102+
// Read the scene
103+
Mat pcTest = loadPLYSimple(sceneFileName.c_str(), 1);
104+
105+
// Match the model to the scene and get the pose
106+
cout << endl << "Starting matching..." << endl;
107+
vector<Pose3DPtr> results;
108+
tick1 = cv::getTickCount();
109+
detector.match(pcTest, results, 1.0/40.0, 0.05);
110+
tick2 = cv::getTickCount();
111+
cout << endl << "PPF Elapsed Time " <<
112+
(tick2-tick1)/cv::getTickFrequency() << " sec" << endl;
113+
114+
// Get only first N results
115+
int N = 2;
116+
vector<Pose3DPtr> resultsSub(results.begin(),results.begin()+N);
117+
118+
// Create an instance of ICP
119+
ICP icp(100, 0.005f, 2.5f, 8);
120+
int64 t1 = cv::getTickCount();
121+
122+
// Register for all selected poses
123+
cout << endl << "Performing ICP on " << N << " poses..." << endl;
124+
icp.registerModelToScene(pc, pcTest, resultsSub);
125+
int64 t2 = cv::getTickCount();
126+
127+
cout << endl << "ICP Elapsed Time " <<
128+
(t2-t1)/cv::getTickFrequency() << " sec" << endl;
129+
130+
cout << "Poses: " << endl;
131+
// debug first five poses
132+
for (size_t i=0; i<resultsSub.size(); i++)
133+
{
134+
Pose3DPtr result = resultsSub[i];
135+
cout << "Pose Result " << i << endl;
136+
result->printPose();
137+
if (i==0)
138+
{
139+
Mat pct = transformPCPose(pc, result->pose);
140+
writePLY(pct, "para6700PCTrans.ply");
141+
}
142+
}
143+
144+
return 0;
145+
146+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
3+
//
4+
// By downloading, copying, installing or using the software you agree to this license.
5+
// If you do not agree to this license, do not download, install,
6+
// copy or use the software.
7+
//
8+
//
9+
// License Agreement
10+
// For Open Source Computer Vision Library
11+
//
12+
// Copyright (C) 2014, OpenCV Foundation, all rights reserved.
13+
// Third party copyrights are property of their respective owners.
14+
//
15+
// Redistribution and use in source and binary forms, with or without modification,
16+
// are permitted provided that the following conditions are met:
17+
//
18+
// * Redistribution's of source code must retain the above copyright notice,
19+
// this list of conditions and the following disclaimer.
20+
//
21+
// * Redistribution's in binary form must reproduce the above copyright notice,
22+
// this list of conditions and the following disclaimer in the documentation
23+
// and/or other materials provided with the distribution.
24+
//
25+
// * The name of the copyright holders may not be used to endorse or promote products
26+
// derived from this software without specific prior written permission.
27+
//
28+
// This software is provided by the copyright holders and contributors "as is" and
29+
// any express or implied warranties, including, but not limited to, the implied
30+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
31+
// In no event shall the Intel Corporation or contributors be liable for any direct,
32+
// indirect, incidental, special, exemplary, or consequential damages
33+
// (including, but not limited to, procurement of substitute goods or services;
34+
// loss of use, data, or profits; or business interruption) however caused
35+
// and on any theory of liability, whether in contract, strict liability,
36+
// or tort (including negligence or otherwise) arising in any way out of
37+
// the use of this software, even if advised of the possibility of such damage.
38+
#ifndef __OPENCV_SURFACE_MATCHING_HPP__
39+
#define __OPENCV_SURFACE_MATCHING_HPP__
40+
41+
#include "surface_matching/ppf_match_3d.hpp"
42+
#include "surface_matching/icp.hpp"
43+
44+
#endif
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
//
2+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
3+
//
4+
// By downloading, copying, installing or using the software you agree to this license.
5+
// If you do not agree to this license, do not download, install,
6+
// copy or use the software.
7+
//
8+
//
9+
// License Agreement
10+
// For Open Source Computer Vision Library
11+
//
12+
// Copyright (C) 2014, OpenCV Foundation, all rights reserved.
13+
// Third party copyrights are property of their respective owners.
14+
//
15+
// Redistribution and use in source and binary forms, with or without modification,
16+
// are permitted provided that the following conditions are met:
17+
//
18+
// * Redistribution's of source code must retain the above copyright notice,
19+
// this list of conditions and the following disclaimer.
20+
//
21+
// * Redistribution's in binary form must reproduce the above copyright notice,
22+
// this list of conditions and the following disclaimer in the documentation
23+
// and/or other materials provided with the distribution.
24+
//
25+
// * The name of the copyright holders may not be used to endorse or promote products
26+
// derived from this software without specific prior written permission.
27+
//
28+
// This software is provided by the copyright holders and contributors "as is" and
29+
// any express or implied warranties, including, but not limited to, the implied
30+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
31+
// In no event shall the Intel Corporation or contributors be liable for any direct,
32+
// indirect, incidental, special, exemplary, or consequential damages
33+
// (including, but not limited to, procurement of substitute goods or services;
34+
// loss of use, data, or profits; or business interruption) however caused
35+
// and on any theory of liability, whether in contract, strict liability,
36+
// or tort (including negligence or otherwise) arising in any way out of
37+
// the use of this software, even if advised of the possibility of such damage.
38+
//
39+
// Author: Tolga Birdal <tbirdal AT gmail.com>
40+
41+
42+
/**
43+
* @file icp.hpp
44+
*
45+
* @brief Implementation of ICP (Iterative Closest Point) Algorithm
46+
* @author Tolga Birdal
47+
*/
48+
49+
#ifndef __OPENCV_SURFACE_MATCHING_ICP_HPP__
50+
#define __OPENCV_SURFACE_MATCHING_ICP_HPP__
51+
52+
#include <opencv2/core.hpp>
53+
54+
#include "pose_3d.hpp"
55+
#include <vector>
56+
57+
namespace cv
58+
{
59+
namespace ppf_match_3d
60+
{
61+
/**
62+
* @class ICP
63+
* @brief This class implements a very efficient and robust variant of the iterative closest point (ICP) algorithm.
64+
* The task is to register a 3D model (or point cloud) against a set of noisy target data. The variants are put together
65+
* by myself after certain tests. The task is to be able to match partial, noisy point clouds in cluttered scenes, quickly.
66+
* You will find that my emphasis is on the performance, while retaining the accuracy.
67+
* This implementation is based on Tolga Birdal's MATLAB implementation in here:
68+
* http://www.mathworks.com/matlabcentral/fileexchange/47152-icp-registration-using-efficient-variants-and-multi-resolution-scheme
69+
* The main contributions come from:
70+
* 1. Picky ICP:
71+
* http://www5.informatik.uni-erlangen.de/Forschung/Publikationen/2003/Zinsser03-ARI.pdf
72+
* 2. Efficient variants of the ICP Algorithm:
73+
* http://docs.happycoders.org/orgadoc/graphics/imaging/fasticp_paper.pdf
74+
* 3. Geometrically Stable Sampling for the ICP Algorithm: https://graphics.stanford.edu/papers/stabicp/stabicp.pdf
75+
* 4. Multi-resolution registration:
76+
* http://www.cvl.iis.u-tokyo.ac.jp/~oishi/Papers/Alignment/Jost_MultiResolutionICP_3DIM03.pdf
77+
* 5. Linearization of Point-to-Plane metric by Kok Lim Low:
78+
* https://www.comp.nus.edu.sg/~lowkl/publications/lowk_point-to-plane_icp_techrep.pdf
79+
*/
80+
class CV_EXPORTS ICP
81+
{
82+
public:
83+
84+
enum ICP_SAMPLING_TYPE
85+
{
86+
ICP_SAMPLING_TYPE_UNIFORM,
87+
ICP_SAMPLING_TYPE_GELFAND
88+
};
89+
90+
ICP()
91+
{
92+
m_tolerance = 0.005f;
93+
m_rejectionScale = 2.5f;
94+
m_maxIterations = 250;
95+
m_numLevels = 6;
96+
m_sampleType = ICP_SAMPLING_TYPE_UNIFORM;
97+
m_numNeighborsCorr = 1;
98+
}
99+
100+
virtual ~ICP() { }
101+
102+
/**
103+
* \brief ICP constructor with default arguments.
104+
* @param [in] tolerence Controls the accuracy of registration at each iteration of ICP.
105+
* @param [in] rejectionScale Robust outlier rejection is applied for robustness. This value actually corresponds to the standard deviation coefficient. Points with rejectionScale * \sigma are ignored during registration.
106+
* @param [in] numLevels Number of pyramid levels to proceed. Deep pyramids increase speed but decrease accuracy. Too coarse pyramids might have computational overhead on top of the inaccurate registrtaion. This parameter should be chosen to optimize a balance. Typical values range from 4 to 10.
107+
* @param [in] sampleType Currently this parameter is ignored and only uniform sampling is applied. Leave it as 0.
108+
* @param [in] numMaxCorr Currently this parameter is ignored and only PickyICP is applied. Leave it as 1.
109+
* \return
110+
*
111+
* \details Constructor
112+
*/
113+
ICP(const int iterations, const float tolerence=0.05, const float rejectionScale=2.5, const int numLevels=6, const ICP_SAMPLING_TYPE sampleType = ICP_SAMPLING_TYPE_UNIFORM, const int numMaxCorr=1)
114+
{
115+
m_tolerance = tolerence;
116+
m_numNeighborsCorr = numMaxCorr;
117+
m_rejectionScale = rejectionScale;
118+
m_maxIterations = iterations;
119+
m_numLevels = numLevels;
120+
m_sampleType = sampleType;
121+
}
122+
123+
/**
124+
* \brief Perform registration
125+
*
126+
* @param [in] srcPC The input point cloud for the model. Expected to have the normals (Nx6). Currently,
127+
* CV_32F is the only supported data type.
128+
* @param [in] dstPC The input point cloud for the scene. It is assumed that the model is registered on the scene. Scene remains static. Expected to have the normals (Nx6). Currently, CV_32F is the only supported data type.
129+
* @param [out] residual The output registration error.
130+
* @param [out] pose Transformation between srcPC and dstPC.
131+
* \return On successful termination, the function returns 0.
132+
*
133+
* \details It is assumed that the model is registered on the scene. Scene remains static, while the model transforms. The output poses transform the models onto the scene. Because of the point to plane minimization, the scene is expected to have the normals available. Expected to have the normals (Nx6).
134+
*/
135+
int registerModelToScene(const Mat& srcPC, const Mat& dstPC, double& residual, double pose[16]);
136+
137+
/**
138+
* \brief Perform registration with multiple initial poses
139+
*
140+
* @param [in] srcPC The input point cloud for the model. Expected to have the normals (Nx6). Currently,
141+
* CV_32F is the only supported data type.
142+
* @param [in] dstPC The input point cloud for the scene. Currently, CV_32F is the only supported data type.
143+
* @param [in,out] poses Input poses to start with but also list output of poses.
144+
* \return On successful termination, the function returns 0.
145+
*
146+
* \details It is assumed that the model is registered on the scene. Scene remains static, while the model transforms. The output poses transform the models onto the scene. Because of the point to plane minimization, the scene is expected to have the normals available. Expected to have the normals (Nx6).
147+
*/
148+
int registerModelToScene(const Mat& srcPC, const Mat& dstPC, std::vector<Pose3DPtr>& poses);
149+
150+
private:
151+
float m_tolerance;
152+
int m_maxIterations;
153+
float m_rejectionScale;
154+
int m_numNeighborsCorr;
155+
int m_numLevels;
156+
int m_sampleType;
157+
158+
};
159+
160+
} // namespace ppf_match_3d
161+
162+
} // namespace cv
163+
164+
#endif

0 commit comments

Comments
 (0)