8 #include "opencv2/opencv.hpp" 9 #include <pcl/point_cloud.h> 10 #include <pcl/io/pcd_io.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> 31 bool getCorners(cv::Mat img, pcl::PointCloud <pcl::PointXYZ> scan, cv::Mat P,
int num_of_markers,
int MAX_ITERS) {
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);
42 pcl::PointCloud <pcl::PointXYZ> pc = scan;
45 cv::Rect frame(0, 0, img.cols, img.rows);
47 cv::Mat image_edge_laser =
project(P, frame, scan, NULL);
48 cv::threshold(image_edge_laser, image_edge_laser, 10, 255, 0);
51 cv::Mat combined_rgb_laser;
52 std::vector <cv::Mat> rgb_laser_channels;
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);
58 cv::merge(rgb_laser_channels, combined_rgb_laser);
60 std::map <std::pair<int, int>, std::vector<float>> c2D_to_3D;
61 std::vector<float> point_3D;
64 for (pcl::PointCloud<pcl::PointXYZ>::iterator pt = pc.points.begin(); pt < pc.points.end(); pt++) {
72 if (xy.inside(frame)) {
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;
83 std::vector<int> LINE_SEGMENTS(num_of_markers, 4);
85 pcl::PointCloud<pcl::PointXYZ>::Ptr board_corners(
new pcl::PointCloud <pcl::PointXYZ>);
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;
92 cv::namedWindow(
"cloud", cv::WINDOW_NORMAL);
93 cv::namedWindow(
"polygon", cv::WINDOW_NORMAL);
96 std::ofstream outfile(pkg_loc +
"/conf/points.txt", std::ios_base::trunc);
97 outfile << num_of_markers * 4 <<
"\n";
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++) {
104 std::vector <cv::Point> polygon;
111 while (collected != LINE_SEGMENTS[q]) {
113 cv::setMouseCallback(
"cloud",
onMouse, &_point_);
115 cv::imshow(
"cloud", image_edge_laser);
118 polygon.push_back(_point_);
125 cv::Mat polygon_image = cv::Mat::zeros(image_edge_laser.size(), CV_8UC1);
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);
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));
140 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud <pcl::PointXYZ>);
141 pcl::PointCloud<pcl::PointXYZ>::Ptr
final(
new pcl::PointCloud <pcl::PointXYZ>);
143 for (std::map < std::pair < int, int >, std::vector < float > > ::iterator it = c2D_to_3D.begin();
144 it != c2D_to_3D.end();
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,
158 if (cloud->size() < 2) {
return false; }
160 cv::imshow(
"polygon", combined_rgb_laser);
163 std::vector<int> inliers;
164 Eigen::VectorXf model_coefficients;
168 pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr model_l(
169 new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud));
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);
178 std::cout <<
"Line coefficients are:" <<
"\n" << model_coefficients <<
"\n";
180 pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *
final);
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;
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";
202 *board_corners += *corners;
204 std::cout <<
"Distance between the corners:\n";
205 for (
int i = 0; i < 4; i++) {
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)
void onMouse(int event, int x, int y, int f, void *g)
bool getCorners(cv::Mat img, pcl::PointCloud< pcl::PointXYZ > scan, cv::Mat P, int num_of_markers, int MAX_ITERS)
cv::Point project(const pcl::PointXYZ &pt, const cv::Mat &projection_matrix)
TFSIMD_FORCE_INLINE const tfScalar & y() const
std::vector< std::vector< cv::Point > > stored_corners
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()