一种区域点云边界估计方法
首先,区域点云边界估计应该说是比较成熟的技术,当然实现方法有很多,大家可以根据具体的应用,选合适的方法。本文的区域点云边界估计是基于点云网格化结果,进行边缘检测的, 具体实现如下:
一、实现思路
1、点云的平滑、去噪、空间均匀抽希。
2、进行点云网格化,网格化也是比较成熟的算法,例如BPA、MPA、Delaunay、贪婪三角形、泊松重建、以及基于NURBS的重建等等。
3、网格边缘点的检测。
4、边缘点连接成闭合曲线。
二、实现代码(部分)
以下为第三步核心代码:
/******************边界估计****************************/ std::vector<std::vector<PointToPoint>> ptp_vect(outPointCloud.size()); for (size_t i = 0; i < face_vect.size(); i++) { int index_temp00 = face_vect[i].p_index_0; int index_temp01 = face_vect[i].p_index_1; int index_temp02 = face_vect[i].p_index_2; int exist01 = 0; int exist02 = 0; int exist03 = 0; for (size_t j = 0; j < ptp_vect[index_temp00].size(); j++) { if (ptp_vect[index_temp00][j].p_index == index_temp01) { exist01 = 1; } if (ptp_vect[index_temp00][j].p_index == index_temp02) { exist02 = 1; } } for (size_t j = 0; j < ptp_vect[index_temp01].size(); j++) { if (ptp_vect[index_temp01][j].p_index == index_temp02) { exist03 = 1; } } if (exist01==1) { for (size_t j = 0; j < ptp_vect[index_temp00].size(); j++) { if (ptp_vect[index_temp00][j].p_index == index_temp01) { ptp_vect[index_temp00][j].ptp_relation++; } } for (size_t j = 0; j < ptp_vect[index_temp01].size(); j++) { if (ptp_vect[index_temp01][j].p_index == index_temp00) { ptp_vect[index_temp01][j].ptp_relation++; } } } else { PointToPoint ptp_temp; ptp_temp.ptp_relation = 1; ptp_temp.p_index = index_temp01; ptp_vect[index_temp00].push_back(ptp_temp); ptp_temp.p_index = index_temp00; ptp_vect[index_temp01].push_back(ptp_temp); } if (exist02 == 1) { for (size_t j = 0; j < ptp_vect[index_temp00].size(); j++) { if (ptp_vect[index_temp00][j].p_index == index_temp02) { ptp_vect[index_temp00][j].ptp_relation++; } } for (size_t j = 0; j < ptp_vect[index_temp02].size(); j++) { if (ptp_vect[index_temp02][j].p_index == index_temp00) { ptp_vect[index_temp02][j].ptp_relation++; } } } else { PointToPoint ptp_temp; ptp_temp.ptp_relation = 1; ptp_temp.p_index = index_temp02; ptp_vect[index_temp00].push_back(ptp_temp); ptp_temp.p_index = index_temp00; ptp_vect[index_temp02].push_back(ptp_temp); } if (exist03 == 1) { for (size_t j = 0; j < ptp_vect[index_temp01].size(); j++) { if (ptp_vect[index_temp01][j].p_index == index_temp02) { ptp_vect[index_temp01][j].ptp_relation++; } } for (size_t j = 0; j < ptp_vect[index_temp02].size(); j++) { if (ptp_vect[index_temp02][j].p_index == index_temp01) { ptp_vect[index_temp02][j].ptp_relation++; } } } else { PointToPoint ptp_temp; ptp_temp.ptp_relation = 1; ptp_temp.p_index = index_temp02; ptp_vect[index_temp01].push_back(ptp_temp); ptp_temp.p_index = index_temp01; ptp_vect[index_temp02].push_back(ptp_temp); } } //检测孤点、外边。 //存储没有构成新三角形的外边,为后面检测边界使用 std::vector<int> singlePoints; //孤点 std::vector<int> point_pos(outPointCloud.size()); //std::vector<int> edgePointsVect; //边界点 for (size_t i = 0; i < ptp_vect.size(); i++) { if (ptp_vect[i].size() == 0) { singlePoints.push_back(i); //说明是孤点 point_pos[i] = 2; continue; } for (size_t j = 0; j < ptp_vect[i].size(); j++) { if (ptp_vect[i][j].ptp_relation == 1) { edgePointsVect.push_back(i); point_pos[i] = 1; //说明是外点 break; } } }
三、效果