PCL提取平面上的圆形凸台特征
1. 点云转深度图像,提取圆心;找到与圆心匹配的三维点;
2. 三维点以指定半径取邻域点,抽取所有邻域点的最大平面为参考平面;
3. 将平面附近点删去,得到凸台点。剩余凸台抽取最大平面,作为凸台顶面平面;
4. 将凸台点云变换到顶面平面作为xOy平面的坐标系下;
5. 对投影到顶面平面的2D点云识别边缘点,并拟合2D圆;找到圆心对应的原始点;
6. 圆心点到参考平面距离为凸台高度;
部分代码如下:
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_src(new pcl::PointCloud<pcl::PointXYZ>);pcl::PLYReader reader;//reader.setVerbosity(true); // 启用详细日志if (reader.read(file_name, *cloud_src) == -1) {pcl::console::print_error("Failed to load PLY file!\n");return -1;}print_time("load data done");#pragma omp parallel forfor (int tt = 0;tt < 100;tt++){pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);*cloud = *cloud_src; // 逐字段深拷贝,包括点、宽、高、header 等Eigen::Vector4f plane_coeff;Eigen::Vector3f centroid;if (!extractPlane(cloud, plane_coeff, centroid)){printf("Plane extract failed!\n");continue;}erasePtsByDistToPlane(cloud, plane_coeff, 0.015);//pcl::io::savePLYFileBinary(folder + "single" + ".ply", *cloud);Eigen::Vector3f centroid2;auto circle_plane = extractLargestPlane(cloud, centroid2);Eigen::Vector4f plane2;plane2[0] = circle_plane->values[0];plane2[1] = circle_plane->values[1];plane2[2] = circle_plane->values[2];plane2[3] = circle_plane->values[3];Coord2DTransformer transformer;transformer.projectToPlane(cloud, plane2, centroid2);//auprojectToPlane(cloud, circle_plane);//pcl::io::savePLYFileBinary(folder + "circle_plane" + ".ply", *cloud2);auto boundary = extractBoundaryPointsAlphaShape(transformer.points2d_cv, 0.01);auto fitted_circle = fitCircleLeastSquares(boundary);auto center = transformer.calcCoord3D(glm::dvec2(fitted_circle.center.x, fitted_circle.center.y));auto height = pointToPlane(center, plane_coeff);// -(plane_coeff[0] * center.x + plane_coeff[1] * center.y + plane_coeff[3] * center.z) / plane_coeff[2];//exportPointsToTXT(boundary, folder + "boundary.txt", 6);printf("center = %.3f, %.3f, %.3f, radius = %.3f, height = %.3f\n",center.x, center.y, center.z, fitted_circle.radius, height);//auto cloud3 = extractBoundary(cloud2);// pcl::io::savePLYFileBinary(folder + "boundary" + ".ply", *cloud3);//Coord2DTransformer transformer;//auto transformed_cloud = transformer.rectify(cloud, plane_coeff, centroid);}