21 #ifndef velo2cam_utils_H 22 #define velo2cam_utils_H 24 #define PCL_NO_PRECOMPILE 30 #include <pcl/point_cloud.h> 31 #include <pcl/point_types.h> 32 #include <pcl/kdtree/kdtree.h> 33 #include <pcl/segmentation/extract_clusters.h> 34 #include <pcl/common/eigen.h> 35 #include <pcl/common/transforms.h> 49 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
52 void addRange(pcl::PointCloud<Velodyne::Point> & pc){
53 for (pcl::PointCloud<Point>::iterator pt = pc.points.begin(); pt < pc.points.end(); pt++)
55 pt->range =
sqrt(pt->x * pt->x + pt->y * pt->y + pt->z * pt->z);
59 vector<vector<Point*> >
getRings(pcl::PointCloud<Velodyne::Point> & pc)
62 for (pcl::PointCloud<Point>::iterator pt = pc.points.begin(); pt < pc.points.end(); pt++)
64 rings[pt->ring].push_back(&(*pt));
72 float min_found = INFINITY;
73 float max_found = -INFINITY;
75 for (pcl::PointCloud<Point>::iterator pt = pc.points.begin(); pt < pc.points.end(); pt++)
77 max_found =
max(max_found, pt->intensity);
78 min_found =
min(min_found, pt->intensity);
81 for (pcl::PointCloud<Point>::iterator pt = pc.points.begin(); pt < pc.points.end(); pt++)
83 pt->intensity = (pt->intensity - min_found) / (max_found - min_found) * (maxv - minv) + minv;
90 (
float, intensity, intensity) (uint16_t, ring, ring) (
float, range, range));
93 double avg_x = 0, avg_y = 0;
94 for(pcl::PointCloud<pcl::PointXYZ>::iterator it=pc->points.begin(); it<pc->points.end(); it++){
103 for(pcl::PointCloud<pcl::PointXYZ>::iterator it=pc->points.begin(); it<pc->points.end(); it++){
104 double x_dif = (*it).x - center.x;
105 double y_dif = (*it).y - center.y;
107 if(x_dif < 0 && y_dif < 0){
109 }
else if(x_dif > 0 && y_dif < 0){
111 }
else if(x_dif > 0 && y_dif > 0){
120 double avg_y = 0, avg_z = 0;
121 for(pcl::PointCloud<pcl::PointXYZ>::iterator it=pc->points.begin(); it<pc->points.end(); it++){
126 pcl::PointXYZ center;
130 for(pcl::PointCloud<pcl::PointXYZ>::iterator it=pc->points.begin(); it<pc->points.end(); it++){
131 double y_dif = (*it).y - center.y;
132 double z_dif = (*it).z - center.z;
134 if(y_dif > 0 && z_dif > 0){
136 }
else if(y_dif < 0 && z_dif > 0){
138 }
else if(y_dif < 0 && z_dif < 0){
146 void colourCenters(
const pcl::PointCloud<pcl::PointXYZ>::Ptr pc, pcl::PointCloud<pcl::PointXYZI>::Ptr coloured){
147 double avg_x = 0, avg_y = 0;
148 for(pcl::PointCloud<pcl::PointXYZ>::iterator it=pc->points.begin(); it<pc->points.end(); it++){
153 pcl::PointXYZ center;
157 for(pcl::PointCloud<pcl::PointXYZ>::iterator it=pc->points.begin(); it<pc->points.end(); it++){
158 double x_dif = (*it).x - center.x;
159 double y_dif = (*it).y - center.y;
167 if(x_dif < 0 && y_dif < 0){
169 }
else if(x_dif > 0 && y_dif < 0){
171 }
else if(x_dif > 0 && y_dif > 0){
176 coloured->push_back(cc);
180 void getCenterClusters(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, pcl::PointCloud<pcl::PointXYZ>::Ptr centers_cloud,
181 double cluster_tolerance = 0.10,
int min_cluster_size = 15,
int max_cluster_size = 200,
bool verbosity=
true){
183 pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (
new pcl::search::KdTree<pcl::PointXYZ>);
184 tree->setInputCloud (cloud_in);
186 std::vector<pcl::PointIndices> cluster_indices;
187 pcl::EuclideanClusterExtraction<pcl::PointXYZ> euclidean_cluster;
188 euclidean_cluster.setClusterTolerance (cluster_tolerance);
189 euclidean_cluster.setMinClusterSize (min_cluster_size);
190 euclidean_cluster.setMaxClusterSize (max_cluster_size);
191 euclidean_cluster.setSearchMethod (tree);
192 euclidean_cluster.setInputCloud (cloud_in);
193 euclidean_cluster.extract (cluster_indices);
195 if(
DEBUG && verbosity) cout << cluster_indices.size() <<
" clusters found from " << cloud_in->points.size() <<
" points in cloud" << endl;
197 for (std::vector<pcl::PointIndices>::iterator it=cluster_indices.begin(); it<cluster_indices.end(); it++) {
198 float accx = 0., accy = 0., accz = 0.;
199 for(vector<int>::iterator it2=it->indices.begin(); it2<it->indices.end(); it2++){
200 accx+=cloud_in->at(*it2).x;
201 accy+=cloud_in->at(*it2).y;
202 accz+=cloud_in->at(*it2).z;
205 pcl::PointXYZ center;
206 center.x = accx/it->indices.size();
207 center.y = accy/it->indices.size();
208 center.z = accz/it->indices.size();
209 centers_cloud->push_back(center);
214 Eigen::Vector3f rotation_vector = target.cross(source);
215 rotation_vector.normalize();
216 double theta =
acos(source[2]/
sqrt(
pow(source[0],2)+
pow(source[1],2) +
pow(source[2],2)));
218 if(
DEBUG)
ROS_INFO(
"Rot. vector: (%lf %lf %lf) / Angle: %lf", rotation_vector[0], rotation_vector[1], rotation_vector[2], theta);
220 Eigen::Matrix3f rotation = Eigen::AngleAxis<float>(theta, rotation_vector) * Eigen::Scaling(1.0
f);
221 Eigen::Affine3f rot(rotation);
void sortPatternCentersXY(pcl::PointCloud< pcl::PointXYZ >::Ptr pc, vector< pcl::PointXYZ > &v)
void sortPatternCentersYZ(pcl::PointCloud< pcl::PointXYZ >::Ptr pc, vector< pcl::PointXYZ > &v)
vector< vector< Point * > > getRings(pcl::PointCloud< Velodyne::Point > &pc)
float intensity
laser intensity reading
POINT_CLOUD_REGISTER_POINT_STRUCT(Velodyne::Point,(float, x, x)(float, y, y)(float, z, z)(float, intensity, intensity)(uint16_t, ring, ring)(float, range, range))
struct Velodyne::Point EIGEN_ALIGN16
uint16_t ring
laser ring number
TFSIMD_FORCE_INLINE const tfScalar & y() const
void normalizeIntensity(pcl::PointCloud< Point > &pc, float minv, float maxv)
void addRange(pcl::PointCloud< Velodyne::Point > &pc)
TFSIMD_FORCE_INLINE const tfScalar & x() const
double min(double a, double b)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
Eigen::Affine3f getRotationMatrix(Eigen::Vector3f source, Eigen::Vector3f target)
void getCenterClusters(pcl::PointCloud< pcl::PointXYZ >::Ptr cloud_in, pcl::PointCloud< pcl::PointXYZ >::Ptr centers_cloud, double cluster_tolerance=0.10, int min_cluster_size=15, int max_cluster_size=200, bool verbosity=true)
TFSIMD_FORCE_INLINE const tfScalar & z() const
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
void colourCenters(const pcl::PointCloud< pcl::PointXYZ >::Ptr pc, pcl::PointCloud< pcl::PointXYZI >::Ptr coloured)
double max(double a, double b)
static const int RINGS_COUNT