PreprocessUtils.h
Go to the documentation of this file.
1 #include <cstdlib>
2 #include <cstdio>
3 #include <iostream>
4 #include <map>
5 #include <fstream>
6 #include <cmath>
7 
8 #include "opencv2/opencv.hpp"
9 #include <pcl/point_cloud.h>
10 #include <pcl/io/pcd_io.h>
11 
12 #include <ros/package.h>
13 
14 #include <pcl_ros/point_cloud.h>
15 #include <boost/foreach.hpp>
17 
18 #include <linux/version.h>
19 
20 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
21 #include <velodyne_pointcloud/point_types.h>
22 #else
23 
24 #include <velodyne_pcl/point_types.h>
25 
26 #endif
27 
28 #include <pcl/common/eigen.h>
29 #include <pcl/common/transforms.h>
30 #include <pcl/filters/passthrough.h>
31 #include <pcl/sample_consensus/ransac.h>
32 #include <pcl/sample_consensus/sac_model_line.h>
33 #include <pcl/common/intersections.h>
34 
35 //------------- PointT declaration ---------------//
36 
37 struct myPointXYZRID {
38  PCL_ADD_POINT4D; // quad-word XYZ
39  float intensity;
40  uint16_t ring;
41  float range;
42  EIGEN_MAKE_ALIGNED_OPERATOR_NEW // ensure proper alignment
43 };
44 
47 (float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity) (uint16_t, ring, ring))
48 
49 namespace Hesai {
50  struct PointXYZIT {
52  float intensity;
53  double timestamp;
54  uint16_t ring;
55  float range;
56  EIGEN_MAKE_ALIGNED_OPERATOR_NEW // make sure our new allocators are aligned
57  };
58 
59  typedef pcl::PointCloud<::Hesai::PointXYZIT> PointCloud;
60 
61 }; // namespace Hesai
62 
64 (float, x, x)(float, y, y)(float, z, z)
65 (float, intensity, intensity)(double, timestamp, timestamp)(uint16_t, ring, ring))
66 
67 //------------- config utils ---------------//
68 
69 struct config_settings {
70  cv::Size s; //image width and height
71  std::vector <std::pair<float, float>> xyz_; //filter point cloud to region of interest
72  float intensity_thresh; //intensity thresh
73  int num_of_markers;
74  bool useCameraInfo;
75  cv::Mat P;
76  int MAX_ITERS;
77  std::vector<float> initialRot;
78  std::vector<float> initialTra;
79  int lidar_type; //0: velodyne, 1: hesai
80 
81  void print() {
82  std::cout << "Size of the frame: " << s.width << " x " << s.height << "\n";
83  for (int i = 0; i < 3; i++) {
84  std::cout << "Limits: " << xyz_[i].first << " to " << xyz_[i].second << std::endl;
85  }
86  std::cout << "Number of markers: " << num_of_markers << std::endl;
87  std::cout << "Intensity threshold (between 0.0 and 1.0): " << intensity_thresh << "\nuseCameraInfo: "
88  << useCameraInfo << "\n";
89  std::cout << "Projection matrix: \n" << P << "\n";
90  std::cout << "MAX_ITERS: " << MAX_ITERS << "\n";
91  std::cout << "Lidar_type: " << ((lidar_type == 0) ? "Velodyne\n" : "Hesai\n");
92 
93  std::cout << "initial rotation: "
94  << initialRot[0] << " "
95  << initialRot[1] << " "
96  << initialRot[2] << "\n";
97 
98  std::cout << "initial translation: "
99  << initialTra[0] << " "
100  << initialTra[1] << " "
101  << initialTra[2] << "\n";
102  }
104 
105 void readConfig() {
106  std::string pkg_loc = ros::package::getPath("lidar_camera_calibration");
107  //std::cout<< "The conf file location: " << pkg_loc <<"/conf/config_file.txt" << std::endl;
108  std::ifstream infile(pkg_loc + "/conf/config_file.txt");
109  float left_limit = 0.0, right_limit = 0.0;
110  float angle;
111  float dist;
112 
113  infile >> config.s.width >> config.s.height;
114  for (int i = 0; i < 3; i++) {
115  infile >> left_limit >> right_limit;
116  config.xyz_.push_back(std::pair<float, float>(left_limit, right_limit));
117  }
118 
119  infile >> config.intensity_thresh >> config.num_of_markers >> config.useCameraInfo;
120  float p[12];
121  for (int i = 0; i < 12; i++) {
122  infile >> p[i];
123  }
124  cv::Mat(3, 4, CV_32FC1, &p).copyTo(config.P);
125 
126  infile >> config.MAX_ITERS;
127 
128  for (int i = 0; i < 3; i++) {
129  infile >> angle;
130  config.initialRot.push_back(angle);
131  }
132 
133  for (int i = 0; i < 3; i++) {
134  infile >> dist;
135  config.initialTra.push_back(dist);
136  }
137 
138  infile >> config.lidar_type;
139 
140  infile.close();
141  config.print();
142 }
143 
144 //------------- point cloud utils ---------------//
145 pcl::PointCloud<myPointXYZRID>::Ptr toMyPointXYZRID(const Hesai::PointCloud &point_cloud_ptr) {
146  pcl::PointCloud<myPointXYZRID>::Ptr new_cloud(new pcl::PointCloud <myPointXYZRID>);
147  for (auto pt = point_cloud_ptr.points.begin(); pt < point_cloud_ptr.points.end(); pt++) {
148  myPointXYZRID myPt;
149  myPt.x = pt->x;
150  myPt.y = pt->y;
151  myPt.z = pt->z;
152  myPt.intensity = pt->intensity;
153  myPt.ring = pt->ring;
154  myPt.range = pt->range;
155  new_cloud->push_back(myPt);
156  }
157  return new_cloud;
158 }
159 
160 pcl::PointCloud <pcl::PointXYZ> *toPointsXYZ(pcl::PointCloud <myPointXYZRID> point_cloud) {
161  pcl::PointCloud <pcl::PointXYZ> *new_cloud = new pcl::PointCloud<pcl::PointXYZ>();
162  for (pcl::PointCloud<myPointXYZRID>::iterator pt = point_cloud.points.begin();
163  pt < point_cloud.points.end(); pt++) {
164  new_cloud->push_back(pcl::PointXYZ(pt->x, pt->y, pt->z));
165  }
166  return new_cloud;
167 }
168 
169 
170 pcl::PointCloud <myPointXYZRID>
171 transform(pcl::PointCloud <myPointXYZRID> pc, float x, float y, float z, float rot_x, float rot_y, float rot_z) {
172  Eigen::Affine3f transf = pcl::getTransformation(x, y, z, rot_x, rot_y, rot_z);
173  pcl::PointCloud <myPointXYZRID> new_cloud;
174  pcl::transformPointCloud(pc, new_cloud, transf);
175  return new_cloud;
176 }
177 
178 
179 pcl::PointCloud <myPointXYZRID> normalizeIntensity(pcl::PointCloud <myPointXYZRID> point_cloud, float min, float max) {
180  float min_found = 10e6;
181  float max_found = -10e6;
182 
183  for (pcl::PointCloud<myPointXYZRID>::iterator pt = point_cloud.points.begin();
184  pt < point_cloud.points.end(); pt++) {
185  max_found = MAX(max_found, pt->intensity);
186  min_found = MIN(min_found, pt->intensity);
187  }
188 
189  for (pcl::PointCloud<myPointXYZRID>::iterator pt = point_cloud.points.begin();
190  pt < point_cloud.points.end(); pt++) {
191  pt->intensity = (pt->intensity - min_found) / (max_found - min_found) * (max - min) + min;
192  }
193  return point_cloud;
194 }
195 
196 
197 pcl::PointCloud <myPointXYZRID>
198 intensityByRangeDiff(pcl::PointCloud <myPointXYZRID> point_cloud, config_settings config) {
199 
200  std::vector <std::vector<myPointXYZRID *>> rings(16);
201 
202  for (pcl::PointCloud<myPointXYZRID>::iterator pt = point_cloud.points.begin();
203  pt < point_cloud.points.end(); pt++) {
204  pt->range = (pt->x * pt->x + pt->y * pt->y + pt->z * pt->z);
205  rings[pt->ring].push_back(&(*pt));
206  }
207 
208  for (std::vector < std::vector < myPointXYZRID * >> ::iterator ring = rings.begin(); ring < rings.end();
209  ring++){
210  myPointXYZRID * prev, *succ;
211  if (ring->empty()) {
212  continue;
213  }
214  float last_intensity = (*ring->begin())->intensity;
215  float new_intensity;
216  (*ring->begin())->intensity = 0;
217  (*(ring->end() - 1))->intensity = 0;
218  for (std::vector<myPointXYZRID *>::iterator pt = ring->begin() + 1; pt < ring->end() - 1; pt++) {
219  prev = *(pt - 1);
220  succ = *(pt + 1);
221 
222 
223  (*pt)->intensity = MAX(MAX(prev->range - (*pt)->range, succ->range - (*pt)->range), 0) * 10;
224  }
225  }
226  point_cloud = normalizeIntensity(point_cloud, 0.0, 1.0);
227 
228  pcl::PointCloud <myPointXYZRID> filtered;
229 
230  for (pcl::PointCloud<myPointXYZRID>::iterator pt = point_cloud.points.begin();
231  pt < point_cloud.points.end(); pt++) {
232  if (pt->intensity > config.intensity_thresh) {
233  if (pt->x >= config.xyz_[0].first && pt->x <= config.xyz_[0].second && pt->y >= config.xyz_[1].first &&
234  pt->y <= config.xyz_[1].second && pt->z >= config.xyz_[2].first && pt->z <= config.xyz_[2].second) {
235  filtered.push_back(*pt);
236  }
237  }
238  }
239 
240  return filtered;
241 }
pcl::PointCloud< myPointXYZRID > intensityByRangeDiff(pcl::PointCloud< myPointXYZRID > point_cloud, config_settings config)
XmlRpcServer s
pcl::PointCloud< myPointXYZRID > normalizeIntensity(pcl::PointCloud< myPointXYZRID > point_cloud, float min, float max)
pcl::PointCloud< pcl::PointXYZ > * toPointsXYZ(pcl::PointCloud< myPointXYZRID > point_cloud)
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
pcl::PointCloud< myPointXYZRID >::Ptr toMyPointXYZRID(const Hesai::PointCloud &point_cloud_ptr)
pcl::PointCloud< myPointXYZRID > transform(pcl::PointCloud< myPointXYZRID > pc, float x, float y, float z, float rot_x, float rot_y, float rot_z)
pcl::PointCloud< myPointXYZRID > point_cloud
POINT_CLOUD_REGISTER_POINT_STRUCT(myPointXYZRID,(float, x, x)(float, y, y)(float, z, z)(float, intensity, intensity)(uint16_t, ring, ring)) namespace Hesai
ROSLIB_DECL std::string getPath(const std::string &package_name)
uint16_t ring
laser ring number
void readConfig()
float intensity
laser intensity reading
config
void print(cv::Point3f p, string cad)
std::string pkg_loc
Definition: Find_RT.h:17


lidar_camera_calibration
Author(s):
autogenerated on Sat Feb 6 2021 03:39:37