00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <pcl/apps/modeler/icp_registration_worker.h>
00038 #include <pcl/apps/modeler/parameter_dialog.h>
00039 #include <pcl/apps/modeler/parameter.h>
00040 #include <pcl/apps/modeler/cloud_mesh.h>
00041 #include <pcl/apps/modeler/cloud_mesh_item.h>
00042 #include <pcl/registration/icp.h>
00043 #include <pcl/common/common.h>
00044
00046 pcl::modeler::ICPRegistrationWorker::ICPRegistrationWorker(CloudMesh::PointCloudPtr cloud, const QList<CloudMeshItem*>& cloud_mesh_items, QWidget* parent)
00047 : AbstractWorker(cloud_mesh_items, parent),
00048 cloud_(cloud),
00049 x_min_(std::numeric_limits<double>::max()), x_max_(std::numeric_limits<double>::min()),
00050 y_min_(std::numeric_limits<double>::max()), y_max_(std::numeric_limits<double>::min()),
00051 z_min_(std::numeric_limits<double>::max()), z_max_(std::numeric_limits<double>::min()),
00052 max_correspondence_distance_(NULL),
00053 max_iterations_(NULL),
00054 transformation_epsilon_(NULL),
00055 euclidean_fitness_epsilon_(NULL)
00056 {
00057
00058 }
00059
00061 pcl::modeler::ICPRegistrationWorker::~ICPRegistrationWorker(void)
00062 {
00063 }
00064
00066 void
00067 pcl::modeler::ICPRegistrationWorker::initParameters(CloudMeshItem* cloud_mesh_item)
00068 {
00069 cloud_->clear();
00070
00071 Eigen::Vector4f min_pt, max_pt;
00072 pcl::getMinMax3D(*(cloud_mesh_item->getCloudMesh()->getCloud()), min_pt, max_pt);
00073
00074 x_min_ = std::min(double(min_pt.x()), x_min_);
00075 x_max_ = std::max(double(max_pt.x()), x_max_);
00076
00077 y_min_ = std::min(double(min_pt.y()), y_min_);
00078 y_max_ = std::max(double(max_pt.y()), y_max_);
00079
00080 z_min_ = std::min(double(min_pt.z()), z_min_);
00081 z_max_ = std::max(double(max_pt.z()), z_max_);
00082
00083 return;
00084 }
00085
00087 void
00088 pcl::modeler::ICPRegistrationWorker::setupParameters()
00089 {
00090 double x_range = x_max_ - x_min_;
00091 double y_range = y_max_ - y_min_;
00092 double z_range = z_max_ - z_min_;
00093
00094 double range_max = std::max(x_range, std::max(y_range, z_range));
00095 double max_correspondence_distance = range_max/2;
00096 double step = range_max/1000;
00097
00098 max_correspondence_distance_ = new DoubleParameter("Max Correspondence Distance",
00099 "If the distance is larger than this threshold, the points will be ignored in the alignment process.", max_correspondence_distance, 0, x_max_-x_min_, step);
00100
00101 max_iterations_ = new IntParameter("Max Iterations",
00102 "Set the maximum number of iterations the internal optimization should run for.", 10, 0, 256);
00103
00104 double transformation_epsilon = range_max/2;
00105 transformation_epsilon_ = new DoubleParameter("Transformation Epsilon",
00106 "Maximum allowable difference between two consecutive transformations.", 0.0, 0, transformation_epsilon, step);
00107
00108 double euclidean_fitness_epsilon = range_max/2;
00109 euclidean_fitness_epsilon_ = new DoubleParameter("Euclidean Fitness Epsilon",
00110 "Maximum allowed Euclidean error between two consecutive steps in the ICP loop.", 0.0, 0, euclidean_fitness_epsilon, step);
00111
00112 parameter_dialog_->addParameter(max_correspondence_distance_);
00113 parameter_dialog_->addParameter(max_iterations_);
00114 parameter_dialog_->addParameter(transformation_epsilon_);
00115 parameter_dialog_->addParameter(euclidean_fitness_epsilon_);
00116
00117 return;
00118 }
00119
00121 void
00122 pcl::modeler::ICPRegistrationWorker::processImpl(CloudMeshItem* cloud_mesh_item)
00123 {
00124 if (cloud_->empty())
00125 {
00126 *cloud_ = *(cloud_mesh_item->getCloudMesh()->getCloud());
00127 return;
00128 }
00129
00130 pcl::IterativeClosestPoint<CloudMesh::PointT, CloudMesh::PointT> icp;
00131
00132
00133 icp.setMaxCorrespondenceDistance (*max_correspondence_distance_);
00134
00135 icp.setMaximumIterations (*max_iterations_);
00136
00137 icp.setTransformationEpsilon (*transformation_epsilon_);
00138
00139 icp.setEuclideanFitnessEpsilon (*euclidean_fitness_epsilon_);
00140
00141 icp.setInputCloud(cloud_mesh_item->getCloudMesh()->getCloud());
00142 icp.setInputTarget(cloud_);
00143 pcl::PointCloud<CloudMesh::PointT> result;
00144 icp.align(result);
00145
00146 result.sensor_origin_ = cloud_mesh_item->getCloudMesh()->getCloud()->sensor_origin_;
00147 result.sensor_orientation_ = cloud_mesh_item->getCloudMesh()->getCloud()->sensor_orientation_;
00148
00149 *(cloud_mesh_item->getCloudMesh()->getCloud()) = result;
00150 *cloud_ += result;
00151
00152 return;
00153 }