PointCloudLibrary / PointCloudLibrary/pcl

[surface] Unexpected results from pcl::surface::MarchingCubes

Open
#3,961 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind: bug module: surface needs: testing
Dominant language
C++
Stars
11.1k
Forks
4.7k
Avg merge
4d 10h
Merged PRs (30d)
6

Description

Describe the bug

The pcl::surface::MarchingCubes algorithm gives unexpected results with seemingly random patterns.

Context

I tried to reconstruct a mesh (ply or stl, but not really relevant to reproduce the issue) from a .pcd file.

Expected behavior

I expected a correct approximation of the input point cloud as mesh (at least after playing with the voxel size).

Current Behavior

The output mesh represents the input cloud to a certain degree, but has a lot of seemingly random data not present in the original cloud.

To Reproduce

Use the attached code and this example PCD file to reconstruct a mesh using MarchingCubes.

Screenshots/Code snippets

The Original PCD:
The Original PCD

The reconstructed mesh (in MeshLab):
The reconstructed mesh (in MeshLab)

The code:

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/surface/marching_cubes.h>
#include <pcl/surface/marching_cubes_hoppe.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>

#define VOXEL_RES 100


using namespace pcl;

int main (int argc, char** argv)
{
    if (argc < 2)
    {
        std::cerr << "Usage: " << argv[0] << " <pcdfile>" << std::endl;
        return -1;
    }
    // Load point cloud from disk
    PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
    if (pcl::io::loadPCDFile<pcl::PointXYZ> (argv[1], *cloud) == -1) //* load the file
    {
        PCL_ERROR ("Couldn't read pcd file.\n");
        return (-1);
    }
    std::cout << "Loaded "
              << cloud->width * cloud->height
              << " data points from \"" << argv[1] << "\"."
              << std::endl;

    // Normal estimation for loaded point cloud
    search::KdTree<PointXYZ>::Ptr tree (new search::KdTree<PointXYZ>);
    tree->setInputCloud(cloud);
    NormalEstimation<PointXYZ, Normal> n;
    n.setInputCloud(cloud);
    n.setSearchMethod(tree);
    n.setKSearch(20);
    PointCloud<Normal>::Ptr normals (new PointCloud<Normal>);
    n.compute(*normals);

    // Concat XYZ and normal values
    PointCloud<PointNormal>::Ptr normalCloud (new PointCloud<PointNormal>);
    concatenateFields(*cloud, *normals, *normalCloud);


    // Create search tree
    search::KdTree<PointNormal>::Ptr tree1 (new search::KdTree<PointNormal>);
    tree1->setInputCloud (normalCloud);
    // Use MarchingCubes to generate a mesh
    PolygonMesh::Ptr output (new PolygonMesh);
    MarchingCubesHoppe<PointNormal> mc;
    PointCloud<PointNormal>::ConstPtr tmpCloudConstPtr (normalCloud);
    mc.setInputCloud (tmpCloudConstPtr);
    mc.setSearchMethod(tree1);
    mc.setGridResolution(VOXEL_RES, VOXEL_RES, VOXEL_RES);
    mc.reconstruct (*output);
    io::savePCDFileASCII ("output.pcd", *normalCloud);


    cout << "Created " << output->polygons.size() << " triangles." << endl;

    // Save the PolygonMesh to an .stl file
    io::savePolygonFileSTL ("output.stl", *output);


    return (0);
}

Environment

  • OS: Ubuntu 18.04
  • Compiler: g++ 7.5.0
  • PCL Version: 1.8, but still persistent in 1.10.1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the result with the attached C++ program and box.pcd file, starting at pcl/surface/marching_cubes_hoppe.h and the MarchingCubesHoppe entry point. Inspect how the estimated normals, search method, and grid resolution affect reconstruction, then verify that the generated STL no longer contains the reported random patterns.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-vision
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.