Corners.cpp
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 #include <velodyne_pcl/point_types.h>
18 #include <pcl/common/eigen.h>
19 #include <pcl/common/transforms.h>
20 #include <pcl/filters/passthrough.h>
21 #include <pcl/sample_consensus/ransac.h>
22 #include <pcl/sample_consensus/sac_model_line.h>
23 #include <pcl/common/intersections.h>
24 
25 
27 
29 std::vector <std::vector<cv::Point>> stored_corners;
30 
31 bool getCorners(cv::Mat img, pcl::PointCloud <pcl::PointXYZ> scan, cv::Mat P, int num_of_markers, int MAX_ITERS) {
32 
33  ROS_INFO_STREAM("iteration number: " << iteration_count << "\n");
34 
35  // Masking happens here
36  cv::Mat edge_mask = cv::Mat::zeros(img.size(), CV_8UC1);
37  edge_mask(cv::Rect(0, 0, img.cols, img.rows)) = 1;
38  img.copyTo(edge_mask, edge_mask);
39 
40  img = edge_mask;
41 
42  pcl::PointCloud <pcl::PointXYZ> pc = scan;
43  // scan = Velodyne::Velodyne(filtered_pc);
44 
45  cv::Rect frame(0, 0, img.cols, img.rows);
46 
47  cv::Mat image_edge_laser = project(P, frame, scan, NULL);
48  cv::threshold(image_edge_laser, image_edge_laser, 10, 255, 0);
49 
50 
51  cv::Mat combined_rgb_laser;
52  std::vector <cv::Mat> rgb_laser_channels;
53 
54  rgb_laser_channels.push_back(image_edge_laser);
55  rgb_laser_channels.push_back(cv::Mat::zeros(image_edge_laser.size(), CV_8UC1));
56  rgb_laser_channels.push_back(img);
57 
58  cv::merge(rgb_laser_channels, combined_rgb_laser);
59 
60  std::map <std::pair<int, int>, std::vector<float>> c2D_to_3D;
61  std::vector<float> point_3D;
62 
63  // store correspondences
64  for (pcl::PointCloud<pcl::PointXYZ>::iterator pt = pc.points.begin(); pt < pc.points.end(); pt++) {
65 
66  // ignore points behind the camera
67  if (pt->z < 0) {
68  continue;
69  }
70 
71  cv::Point xy = project(*pt, P);
72  if (xy.inside(frame)) {
73  // create a map of 2D and 3D points
74  point_3D.clear();
75  point_3D.push_back(pt->x);
76  point_3D.push_back(pt->y);
77  point_3D.push_back(pt->z);
78  c2D_to_3D[std::pair<int, int>(xy.x, xy.y)] = point_3D;
79  }
80  }
81 
82  // get region of interest
83  std::vector<int> LINE_SEGMENTS(num_of_markers, 4); // assuming each has 4 edges and 4 corners
84 
85  pcl::PointCloud<pcl::PointXYZ>::Ptr board_corners(new pcl::PointCloud <pcl::PointXYZ>);
86 
87  pcl::PointCloud<pcl::PointXYZ>::Ptr marker(new pcl::PointCloud <pcl::PointXYZ>);
88  std::vector <cv::Point3f> c_3D;
89  std::vector <cv::Point2f> c_2D;
90 
91 
92  cv::namedWindow("cloud", cv::WINDOW_NORMAL);
93  cv::namedWindow("polygon", cv::WINDOW_NORMAL);
94 
95  std::string pkg_loc = ros::package::getPath("lidar_camera_calibration");
96  std::ofstream outfile(pkg_loc + "/conf/points.txt", std::ios_base::trunc);
97  outfile << num_of_markers * 4 << "\n";
98 
99  for (int q = 0; q < num_of_markers; q++) {
100  std::cout << "---------Moving on to next marker--------\n";
101  std::vector <Eigen::VectorXf> line_model;
102  for (int i = 0; i < LINE_SEGMENTS[q]; i++) {
103  cv::Point _point_;
104  std::vector <cv::Point> polygon;
105  int collected;
106 
107  // get markings in the first iteration only
108  if (iteration_count == 0) {
109  polygon.clear();
110  collected = 0;
111  while (collected != LINE_SEGMENTS[q]) {
112 
113  cv::setMouseCallback("cloud", onMouse, &_point_);
114 
115  cv::imshow("cloud", image_edge_laser);
116  cv::waitKey(0);
117  ++collected;
118  polygon.push_back(_point_);
119  }
120  stored_corners.push_back(polygon);
121  }
122 
123  polygon = stored_corners[4 * q + i];
124 
125  cv::Mat polygon_image = cv::Mat::zeros(image_edge_laser.size(), CV_8UC1);
126 
127  rgb_laser_channels.clear();
128  rgb_laser_channels.push_back(image_edge_laser);
129  rgb_laser_channels.push_back(cv::Mat::zeros(image_edge_laser.size(), CV_8UC1));
130  rgb_laser_channels.push_back(cv::Mat::zeros(image_edge_laser.size(), CV_8UC1));
131  cv::merge(rgb_laser_channels, combined_rgb_laser);
132 
133  for (int j = 0; j < 4; j++) {
134  cv::line(combined_rgb_laser, polygon[j],
135  polygon[(j + 1) % 4],
136  cv::Scalar(0, 255, 0));
137  }
138 
139  // initialize PointClouds
140  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud <pcl::PointXYZ>);
141  pcl::PointCloud<pcl::PointXYZ>::Ptr final(new pcl::PointCloud <pcl::PointXYZ>);
142 
143  for (std::map < std::pair < int, int >, std::vector < float > > ::iterator it = c2D_to_3D.begin();
144  it != c2D_to_3D.end();
145  ++it)
146  {
147 
148  if (cv::pointPolygonTest(cv::Mat(polygon), cv::Point(it->first.first, it->first.second), true) > 0) {
149  cloud->push_back(pcl::PointXYZ(it->second[0], it->second[1], it->second[2]));
150  rectangle(combined_rgb_laser,
151  cv::Point(it->first.first, it->first.second),
152  cv::Point(it->first.first, it->first.second),
153  cv::Scalar(0, 0, 255), 3, 8,
154  0); // RED point
155  }
156  }
157 
158  if (cloud->size() < 2) { return false; }
159 
160  cv::imshow("polygon", combined_rgb_laser);
161  cv::waitKey(4);
162 
163  std::vector<int> inliers;
164  Eigen::VectorXf model_coefficients;
165 
166 
167  // created RandomSampleConsensus object and compute the appropriated model
168  pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr model_l(
169  new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud));
170 
171  pcl::RandomSampleConsensus <pcl::PointXYZ> ransac(model_l);
172  ransac.setDistanceThreshold(0.01);
173  ransac.computeModel();
174  ransac.getInliers(inliers);
175  ransac.getModelCoefficients(model_coefficients);
176  line_model.push_back(model_coefficients);
177 
178  std::cout << "Line coefficients are:" << "\n" << model_coefficients << "\n";
179  // copies all inliers of the model computed to another PointCloud
180  pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *final);
181  *marker += *final;
182  }
183 
184 
185 
186  // calculate approximate intersection of lines
187  Eigen::Vector4f p1, p2, p_intersect;
188  pcl::PointCloud<pcl::PointXYZ>::Ptr corners(new pcl::PointCloud <pcl::PointXYZ>);
189  for (int i = 0; i < LINE_SEGMENTS[q]; i++) {
190  pcl::lineToLineSegment(line_model[i], line_model[(i + 1) % LINE_SEGMENTS[q]], p1, p2);
191  for (int j = 0; j < 4; j++) {
192  p_intersect(j) = (p1(j) + p2(j)) / 2.0;
193  }
194  c_3D.push_back(cv::Point3f(p_intersect(0), p_intersect(1), p_intersect(2)));
195  corners->push_back(pcl::PointXYZ(p_intersect(0), p_intersect(1), p_intersect(2)));
196  std::cout << "Point of intersection is approximately: \n" << p_intersect << "\n";
197  std::cout << p_intersect(0) << " " << p_intersect(1) << " " << p_intersect(2) << "\n";
198  outfile << p_intersect(0) << " " << p_intersect(1) << " " << p_intersect(2) << "\n";
199 
200  }
201 
202  *board_corners += *corners;
203 
204  std::cout << "Distance between the corners:\n";
205  for (int i = 0; i < 4; i++) {
206  std::cout <<
207  sqrt(
208  pow(c_3D[4 * q + i].x - c_3D[4 * q + (i + 1) % 4].x, 2)
209  + pow(c_3D[4 * q + i].y - c_3D[4 * q + (i + 1) % 4].y, 2)
210  + pow(c_3D[4 * q + i].z - c_3D[4 * q + (i + 1) % 4].z, 2)
211  )
212  << std::endl;
213  }
214 
215 
216  }
217  outfile.close();
218 
219  iteration_count++;
220  if (iteration_count == MAX_ITERS) {
221  ros::shutdown();
222  }
223  return true;
224 }
void onMouse(int event, int x, int y, int f, void *g)
Definition: Utils.h:79
bool getCorners(cv::Mat img, pcl::PointCloud< pcl::PointXYZ > scan, cv::Mat P, int num_of_markers, int MAX_ITERS)
Definition: Corners.cpp:31
cv::Point project(const pcl::PointXYZ &pt, const cv::Mat &projection_matrix)
Definition: Utils.h:33
TFSIMD_FORCE_INLINE const tfScalar & y() const
std::vector< std::vector< cv::Point > > stored_corners
Definition: Corners.cpp:29
TFSIMD_FORCE_INLINE const tfScalar & x() const
ROSLIB_DECL std::string getPath(const std::string &package_name)
TFSIMD_FORCE_INLINE const tfScalar & z() const
#define ROS_INFO_STREAM(args)
ROSCPP_DECL void shutdown()
int iteration_count
Definition: Corners.cpp:28
std::string pkg_loc
Definition: Find_RT.h:17


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