PCL提取平面上的圆形凸台特征

发布于:2025-08-13 ⋅ 阅读:(14) ⋅ 点赞:(0)

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 for
  for (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);
  }


网站公告

今日签到

点亮在社区的每一天
去签到