#include "mypcl.h" namespace ai_matrix { MyPcl *MyPcl::ins = nullptr; MyPcl::GarbageCollector MyPcl::gc; std::mutex MyPcl::mx; MyPcl *MyPcl::getins() { //双层锁,确保线程安全 if (ins == nullptr) { std::lock_guard guard(mx); //防止异常发生不能解锁 if (ins == nullptr) { ins = new MyPcl(); } } return ins; } void MyPcl::compressPCD(const pcl::PointCloud &cloud, std::stringstream &compressedData) { bool showStatistics = false; //设置在标准设备上输出打印出压缩结果信息 // 压缩选项详见 /io/include/pcl/compression/compression_profiles.h pcl::io::compression_Profiles_e compressionProfile = pcl::io::LOW_RES_OFFLINE_COMPRESSION_WITH_COLOR; // 初始化压缩与解压缩对象,其中压缩对象需要设定压缩参数选项,解压缩按照数据源自行判断 pcl::io::OctreePointCloudCompression *PointCloudEncoder; PointCloudEncoder = new pcl::io::OctreePointCloudCompression(compressionProfile, showStatistics); PointCloudEncoder->encodePointCloud(cloud.makeShared(), compressedData); // 压缩点云 delete (PointCloudEncoder); } void MyPcl::insert_plane_line(pcl::PointCloud &line, float x_min, float x_max, float y, float z, unsigned char r, unsigned char g, unsigned char b, float step) { int num = 0; for (float x = x_min; x <= x_max; x += step) { pcl::PointXYZRGB pt; pt.x = x; pt.y = y; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } line.width += num; line.height = 1; } void MyPcl::insert_load_line(pcl::PointCloud &line, float x_min, float x_max, float y_min, float y_max, float z, unsigned char r, unsigned char g, unsigned char b, float step) { int num = 0; for (float x = x_min; x <= x_max; x += step) { pcl::PointXYZRGB pt; pt.x = x; pt.y = y_min; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } for (float x = x_min; x <= x_max; x += step) { pcl::PointXYZRGB pt; pt.x = x; pt.y = y_max; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } for (float y = y_min; y <= y_max; y += step) { pcl::PointXYZRGB pt; pt.x = x_min; pt.y = y; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } for (float y = y_min; y <= y_max; y += step) { pcl::PointXYZRGB pt; pt.x = x_max; pt.y = y; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } line.width += num; line.height = 1; } void MyPcl::insert_bound_line(pcl::PointCloud &line, float y_min, float y_max, float z_min, float z_max, float x, unsigned char r, unsigned char g, unsigned char b, float step) { int num = 0; for (float y = y_min; y <= y_max; y += step) { pcl::PointXYZRGB pt; pt.x = x; pt.y = y; pt.z = z_max; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } for (float z = z_min; z <= z_max; z += step) { pcl::PointXYZRGB pt; pt.x = x; pt.y = y_min; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } for (float z = z_min; z <= z_max; z += step) { pcl::PointXYZRGB pt; pt.x = x; pt.y = y_max; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } line.width += num; line.height = 1; } void MyPcl::insert_object_line(pcl::PointCloud &line, float x_min, float x_max, float y, float z_min, float z_max, unsigned char r, unsigned char g, unsigned char b, float step) { int num = 0; for (float x = x_min; x <= x_max; x += step) { pcl::PointXYZRGB pt; pt.x = x; pt.y = y; pt.z = z_min; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } for (float x = x_min; x <= x_max; x += step) { pcl::PointXYZRGB pt; pt.x = x; pt.y = y; pt.z = z_max; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } for (float z = z_min; z <= z_max; z += step) { pcl::PointXYZRGB pt; pt.x = x_min; pt.y = y; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } for (float z = z_min; z <= z_max; z += step) { pcl::PointXYZRGB pt; pt.x = x_max; pt.y = y; pt.z = z; pt.r = r; pt.g = g; pt.b = b; line.points.push_back(pt); num++; } line.width += num; line.height = 1; } void MyPcl::coords_convert(const pcl::PointCloud &cloud_in, pcl::PointCloud &cloud_out, const Eigen::Matrix4f &tf, float thetaz) { Eigen::Matrix4f tf_use; //沿z轴旋转 Eigen::Matrix4f tfz = Eigen::Matrix4f::Identity(); tfz(0, 0) = cos(thetaz); tfz(0, 1) = -sin(thetaz); tfz(1, 0) = sin(thetaz); tfz(1, 1) = cos(thetaz); //y坐标乘以-1 Eigen::Matrix4f tfy = Eigen::Matrix4f::Identity(); tfy(0, 0) = -1; tf_use = tfz * tfy * tf; //一起旋转,效率更高 pcl::transformPointCloud(cloud_in, cloud_out, tf_use); } void MyPcl::coords_convert(const pcl::PointCloud &cloud_in, pcl::PointCloud &cloud_out, float thetax, float thetay, float thetaz, float radarz, bool reverse) { //绕x轴旋转 Eigen::Matrix4f tfx = Eigen::Matrix4f::Identity(); tfx(1, 1) = cos(thetax); tfx(1, 2) = -sin(thetax); tfx(2, 1) = sin(thetax); tfx(2, 2) = cos(thetax); //绕y轴旋转 Eigen::Matrix4f tfy = Eigen::Matrix4f::Identity(); tfy(0, 0) = cos(thetay); tfy(0, 2) = sin(thetay); tfy(2, 0) = -sin(thetay); tfy(2, 2) = cos(thetay); //沿z轴旋转 Eigen::Matrix4f tfz = Eigen::Matrix4f::Identity(); tfz(0, 0) = cos(thetaz); tfz(0, 1) = -sin(thetaz); tfz(1, 0) = sin(thetaz); tfz(1, 1) = cos(thetaz); Eigen::Matrix4f tf_use = tfz * tfy * tfx; //一起旋转,效率更高 tf_use(2, 3) = radarz; //雷达高度 Eigen::Matrix4f tf_use_inv = tf_use.inverse(); //求逆矩阵 if (reverse) { pcl::transformPointCloud(cloud_in, cloud_out, tf_use_inv); } else { pcl::transformPointCloud(cloud_in, cloud_out, tf_use); } } void MyPcl::cube_cloud(const pcl::PointCloud &cloud_in, std::vector &indices, const Eigen::Vector3f &min, const Eigen::Vector3f &max) { //pcl::CropBox crop; //crop.setMin(Eigen::Vector4f(min(0), min(1), min(2), 1.0)); //crop.setMax(Eigen::Vector4f(max(0), max(1), max(2), 1.0)); //crop.setInputCloud(cloud_in.makeShared()); //crop.setNegative(false); //默认为false,代表取立方体内的点 //crop.filter(indices); for(int i = 0 ; i < cloud_in.points.size(); i ++) { if (min[0] < cloud_in.points[i].x && cloud_in.points[i].x < max[0] && min[1] < cloud_in.points[i].y && cloud_in.points[i].y < max[1] && min[2] < cloud_in.points[i].z && cloud_in.points[i].z < max[2]) { indices.push_back(i); } } } void MyPcl::cube_cloud(const pcl::PointCloud &cloud_in, pcl::PointCloud &cloud_out, const Eigen::Vector3f &min, const Eigen::Vector3f &max) { //pcl::CropBox crop; //crop.setMin(Eigen::Vector4f(min(0), min(1), min(2), 1.0)); //crop.setMax(Eigen::Vector4f(max(0), max(1), max(2), 1.0)); //crop.setInputCloud(cloud_in.makeShared()); //crop.setNegative(false); //默认为false,代表取立方体内的点 //crop.filter(cloud_out); cloud_out.height = 1; //无序点云 cloud_out.is_dense = false; //加上,防止出错 for (int i = 0; i < cloud_in.points.size(); i++) { if (min[0] < cloud_in.points[i].x && cloud_in.points[i].x < max[0] && min[1] < cloud_in.points[i].y && cloud_in.points[i].y < max[1] && min[2] < cloud_in.points[i].z && cloud_in.points[i].z < max[2]) { cloud_out.points.push_back(cloud_in.points[i]); } } } void MyPcl::cube_cloud(const pcl::PointCloud &cloud_in, pcl::PointCloud &cloud_out, std::vector &indices, const Eigen::Vector3f &min, const Eigen::Vector3f &max) { //pcl::CropBox crop; //crop.setMin(Eigen::Vector4f(min(0), min(1), min(2), 1.0)); //crop.setMax(Eigen::Vector4f(max(0), max(1), max(2), 1.0)); //crop.setInputCloud(cloud_in.makeShared()); //crop.setNegative(false); //默认为false,代表取立方体内的点 //crop.filter(cloud_out); //crop.filter(indices); cloud_out.height = 1; //无序点云 cloud_out.is_dense = false; //加上,防止出错 for (int i = 0; i < cloud_in.points.size(); i++) { if (min[0] < cloud_in.points[i].x && cloud_in.points[i].x < max[0] && min[1] < cloud_in.points[i].y && cloud_in.points[i].y < max[1] && min[2] < cloud_in.points[i].z && cloud_in.points[i].z < max[2]) { cloud_out.points.push_back(cloud_in.points[i]); indices.push_back(i); } } } }