使用pcl::MarchingCubesHoppe重建无组织点云产生非流形曲面问题求助
体素化苹果点云MC Hoppe重建切片孔洞问题及解决方法
问题描述
用PCL的Marching Cubes Hoppe算法重建半颗无梗苹果的体素化点云(均匀密集无噪声,来自模拟CT扫描)时,生成的凹面网格出现多处完全/部分贯穿的水平、垂直切片状孔洞:
- 网格顶部存在完全贯穿的切片“孔洞”
- 网格局部前视图呈现怪异的水平/垂直切片图案
试过将点类型改为PointXYZI(利用0.0-1.0强度值),但算法未使用该字段,结果无变化;把网格分辨率提高到128x128x128也没解决问题,反而生成布满孔洞的畸形网格。
原始实现代码
// 定义搜索树 pcl::search::KdTree<pcl::PointXYZ>::Ptr tree = pcl::make_shared<pcl::search::KdTree<pcl::PointXYZ>>(); tree->setInputCloud(m_impl->pointCloud); pcl::PointCloud<pcl::Normal>::Ptr cloud_normals = pcl::make_shared<pcl::PointCloud<pcl::Normal>>(); // 法线计算 pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n; n.setInputCloud(m_impl->pointCloud); n.setSearchMethod(tree); n.setKSearch(20); n.compute(*cloud_normals); pcl::concatenateFields(*m_impl->pointCloud, *cloud_normals, *m_impl->preprocessedCloud); //[...] // 曲面重建 float dist_ignore = -1, percentage_extend_grid = 0.05, iso_level = 0.0; pcl::search::KdTree<pcl::PointNormal>::Ptr tree = pcl::make_shared<pcl::search::KdTree<pcl::PointNormal>>(); tree->setInputCloud(m_impl->preprocessedCloud); pcl::MarchingCubesHoppe<pcl::PointNormal> mch(dist_ignore, percentage_extend_grid, iso_level); mch.setInputCloud(m_impl->preprocessedCloud); mch.setIsoLevel(iso_level); mch.setSearchMethod(tree); mch.setPercentageExtendGrid(percentage_extend_grid); mch.setGridResolution(64, 64, 64);
排查细节
- 使用PCL版本为1.12.1,提供了对应点云文件
- 发现库输出报错信息(之前因Qt GUI未留意):
Failed to find match for field 'intensity'. Failed to find match for field 'normal_x'. Failed to find match for field 'normal_y'. Failed to find match for field 'normal_z'. Failed to find match for field 'curvature'.
该报错提示字段匹配失败,是问题的潜在根源。
有效解决方案
Marching Cubes Hoppe算法无法处理高度体素化的点云,可改用pcl::ConcaveHull(alpha形状)直接重建凹面网格,或在应用MC前先用该算法预处理点云,示例代码如下:
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree = pcl::make_shared<pcl::search::KdTree<pcl::PointXYZ>>(); tree->setInputCloud(m_impl->pointCloud); pcl::PointCloud<pcl::PointXYZ>::Ptr concaveCloud = pcl::make_shared<pcl::PointCloud<pcl::PointXYZ>>(); pcl::ConcaveHull<pcl::PointXYZ> concave; concave.setInputCloud(m_impl->pointCloud); concave.setAlpha(0.09); concave.setSearchMethod(tree); concave.reconstruct(*concaveCloud);
内容的提问来源于stack exchange,提问作者albrechu
相关产品推荐
相关产品推荐

