PointCloudLibrary / PointCloudLibrary/pcl

MLS Up Sampling only work if using polynomial fit.

Open
#1,958 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs: code review
Dominant language
C++
Stars
11.1k
Forks
4.7k
Avg merge
4d 10h
Merged PRs (30d)
6

Description

Your Environment

  • Operating System and version: Ubuntu 14.04
  • PCL Version: master branch

Expected Behavior

When polynomial fit is not used it would use the mls plane as the surface to project onto.

Current Behavior

It currently returns the original MLS point and normal, so you get several points at the same location.

Possible Solution

These two lines of code should replace this line of code. I have tested it and everything works as expected.

Code to Reproduce

#include <pcl/point_cloud.h>
#include <pcl/surface/mls.h>
#include <pcl/io/pcd_io.h>

int main(int argc, char *argv[])
{
  pcl::PointCloud<pcl::PointXYZ> cloud;
//  std::string id = "baseline";
  std::string id = "simple";
  int gridSize = 50;

  for(unsigned int x = 0; x < gridSize; x++)
  {
    for(unsigned int y = 0; y < gridSize; y++)
    {
      double d = 0.001 * ( (double)rand() / (double)RAND_MAX );
      pcl::PointXYZ pt(x / 10.0  , y / 10.0 , 0.5 * cos(double(x)/10.0) - 0.5 * sin(double(y)/10.0) + d);
      cloud.push_back(pt);
    }
  }
  cloud.is_dense = false;

  pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud(new pcl::PointCloud<pcl::PointXYZ>(cloud));

  pcl::search::KdTree<pcl::PointXYZ>::Ptr input_cloud_tree(new pcl::search::KdTree<pcl::PointXYZ>);
  input_cloud_tree->setSortedResults(false);
  input_cloud_tree->setInputCloud(input_cloud);

  pcl::PointCloud<pcl::PointNormal>::Ptr mls_cloud(new pcl::PointCloud<pcl::PointNormal>());
  pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::Ptr mls(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(true);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_poly_no_upsampling_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(true);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::SAMPLE_LOCAL_PLANE);
  mls->setUpsamplingRadius(0.1);
  mls->setUpsamplingStepSize(0.05);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_poly_sample_local_plane_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(true);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::RANDOM_UNIFORM_DENSITY);
  mls->setPointDensity(500);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_poly_random_uniform_density_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(true);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::VOXEL_GRID_DILATION);
  mls->setDilationVoxelSize(0.2);
  mls->setDilationIterations(10);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_poly_voxel_grid_dilation_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(true);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::DISTINCT_CLOUD);
  mls->setDistinctCloud(input_cloud);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_poly_distinct_cloud_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(false);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_no_poly_no_upsampling_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(false);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::SAMPLE_LOCAL_PLANE);
  mls->setUpsamplingRadius(0.1);
  mls->setUpsamplingStepSize(0.05);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_no_poly_sample_local_plane_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(false);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::RANDOM_UNIFORM_DENSITY);
  mls->setPointDensity(500);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_no_poly_random_uniform_density_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(false);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::VOXEL_GRID_DILATION);
  mls->setDilationVoxelSize(0.2);
  mls->setDilationIterations(10);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_no_poly_voxel_grid_dilation_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  mls_cloud.reset(new pcl::PointCloud<pcl::PointNormal>());
  mls.reset(new pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>());
  mls->setComputeNormals(true);
  mls->setInputCloud(input_cloud);
  mls->setPolynomialFit(false);
  mls->setPolynomialOrder(2);
  mls->setSearchMethod(input_cloud_tree);
  mls->setSearchRadius(0.5);

  mls->setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal>::DISTINCT_CLOUD);
  mls->setDistinctCloud(input_cloud);

  mls->process(*mls_cloud);
  if (!mls_cloud->empty())
  {
    std::string file_path = "/tmp/mls_no_poly_distinct_cloud_" + id + ".pcd";
    pcl::io::savePCDFile(file_path, *mls_cloud);
    PCL_INFO("Wrote file: %s\n", file_path.c_str());
  }

  return 0;
}

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

Start in surface/include/pcl/surface/impl/mls.hpp at the referenced lines 209 and 235-237, then run the provided reproduction with polynomial fitting disabled and each upsampling mode. Confirm the non-polynomial upsampling path projects generated points onto the MLS plane rather than returning duplicate original points, and verify the existing polynomial-fit behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-vision
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.