forked from jandob/pcl_mex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pcl_transform.cpp
127 lines (95 loc) · 4.14 KB
/
pcl_transform.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// c system headers
#include <point_cloud.h>
#include <pcl/common/transforms.h>
#include <Eigen/Core>
// cpp system headers
#include <iostream>
// other headers
#include "mex.h"
#include "./pcl_mex_conversions.h"
// icp headers
//#include <pcl/features/normal_3d.h>
#include <pcl/registration/icp.h>
#include <pcl/registration/icp_nl.h>
#include <pcl/registration/transforms.h>
#include <pcl/filters/filter.h>
//convenient typedefs
typedef pcl::PointNormal PointNormalT;
typedef pcl::PointCloud<PointNormalT> PointCloudWithNormals;
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
double *inMatrix1; /* Mx3 input matrix */
double *inMatrix2; /* Mx3 input matrix */
double *outMatrix; /* output matrix */
/* check for proper number of arguments */
if (nrhs != 2) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs", "Two inputs required.");
}
if (nlhs != 1) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs", "One output required.");
}
/* make sure the second input argument is type double */
//if ( !mxIsDouble(prhs[1]) ||
// mxIsComplex(prhs[1])) {
// mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble", "Input matrix must be type double.");
//}
/* check that number of columns in first input argument is 1 */
if (mxGetN(prhs[0]) != 6) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:not6Columns", "Input must have 6 columns.");
}
if (mxGetN(prhs[1]) != 6) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:not6Columns", "Input must have 6 columns.");
}
/* create a pointer to the real data in the input matrix */
inMatrix1 = mxGetPr(prhs[0]);
inMatrix2 = mxGetPr(prhs[1]);
//inTransform = mxGetPr(prhs[1]);
/* get dimensions of the input matrix */
mwSize nrows1 = mxGetM(prhs[0]);
mwSize nrows2 = mxGetM(prhs[1]);
pcl::PointCloud<pcl::PointNormal>::Ptr src (new pcl::PointCloud<pcl::PointNormal> ());
mxArrayToPointCloud(prhs[0], src);
pcl::PointCloud<pcl::PointNormal>::Ptr tgt (new pcl::PointCloud<pcl::PointNormal> ());
mxArrayToPointCloud(prhs[1], tgt);
//remove NAN points from the cloud
//std::vector<int> indices;
//pcl::removeNaNFromPointCloud(*m.cloud,*m.cloud, indices);
pcl::IterativeClosestPointWithNormals<pcl::PointNormal, pcl::PointNormal> reg;
reg.setTransformationEpsilon (1e-6);
// Set the maximum distance between two correspondences (src<->tgt) to 10cm
// Note: adjust this based on the size of your datasets
reg.setMaxCorrespondenceDistance (0.1);
reg.setRANSACOutlierRejectionThreshold (0.02);
// Not implemented in version on cluster (2019) https://pointclouds.org/documentation/classpcl_1_1_iterative_closest_point_with_normals.html
//reg.setEnforceSameDirectionNormals(true);
//reg.setUseSymmetricObjective(true);
reg.setInputSource (src);
reg.setInputTarget (tgt);
//
// Run the same optimization in a loop and visualize the results
Eigen::Matrix4f Ti = Eigen::Matrix4f::Identity (), prev, targetToSource;
PointCloudWithNormals::Ptr reg_result = src;
reg.setMaximumIterations (2);
for (int i = 0; i < 30; ++i)
{
//PCL_INFO ("Iteration Nr. %d.\n", i);
// save cloud for visualization purpose
src = reg_result;
// Estimate
reg.setInputSource (src);
reg.align (*reg_result);
//accumulate transformation between each Iteration
Ti = reg.getFinalTransformation () * Ti;
//if the difference between this transformation and the previous one
//is smaller than the threshold, refine the process by reducing
//the maximal correspondence distance
if (fabs ((reg.getLastIncrementalTransformation () - prev).sum ()) < reg.getTransformationEpsilon ())
reg.setMaxCorrespondenceDistance (reg.getMaxCorrespondenceDistance () - 0.001);
prev = reg.getLastIncrementalTransformation ();
}
//
// Get the transformation from target to source
targetToSource = Ti.inverse();
plhs[0] = matrix4fToMxArray(targetToSource);
}