Skip to content

CropHull 3d not cropping inside #1657

Open
@carlosdcsantos

Description

@carlosdcsantos

The CropHull algorithm works well when you want to crop points outside the hull, either in 2d or 3d but it doesn't work when you want to crop points inside the hull in 3d (but it works in 2d).

Code copied from crop_hull.hpp:

  202     if (crop_outside_ && (crossings[0]&1) + (crossings[1]&1) + (crossings[2]&1) > 1)
  203       output.push_back (input_->points[(*indices_)[index]]);
  204     else if (!crop_outside_)
  205       output.push_back (input_->points[(*indices_)[index]]);

This is clearly wrong. The condition checking if the point is inside or outside the hull is not being checked when crop_outside is false, which means every point is being pushed back to the output if the option to crop inside is selected.

Your Environment

  • Operating System and version: Debian GNU/Linux 8 (jessie) 64-bit
  • Compiler: GCC
  • PCL Version: 1.7.1

Expected Behavior

The filter method should filter points as told by the documentation.

Current Behavior

The filter method is not filtering points inside the hull in a 3d (the default) dimensionality.

Possible Solution

Possible solution:

  202     bool isPointInsideHull = (crossings[0]&1) + (crossings[1]&1) + (crossings[2]&1) > 1
  203     if ((crop_outside_ && isPointInsideHull) || (!crop_outside_ && !isPointInsideHull)) 
  204        output.push_back (input_->points[(*indices_)[index]]);

Code to Reproduce

#include <iostream>
#include <pcl/common/common.h>
#include <pcl-1.7/pcl/point_types.h>
#include <pcl-1.7/pcl/point_cloud.h>
#include <pcl/filters/crop_hull.h>
#include <pcl/surface/convex_hull.h>

#include <boost/shared_ptr.hpp>

int main(int argc, char **argv)
{
  typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;

  pcl::CropHull<pcl::PointXYZ> cropHullFilter;
  boost::shared_ptr<PointCloud> hullCloud(new PointCloud());
  boost::shared_ptr<PointCloud> hullPoints(new PointCloud());
  std::vector<pcl::Vertices> hullPolygons;

  hullCloud->clear();
  {
    pcl::PointXYZ p;
    p.x = -1;
    p.y = -1;
    p.z = -1;
    hullCloud->push_back(p);
    p.z = 1;
    hullCloud->push_back(p);
  }
  {
    pcl::PointXYZ p;
    p.x = -1;
    p.y = 1;
    p.z = -1;
    hullCloud->push_back(p);
    p.z = 1;
    hullCloud->push_back(p);
  }
  {
    pcl::PointXYZ p;
    p.x = 1;
    p.y = 1;
    p.z = -1;
    hullCloud->push_back(p);
    p.z = 1;
    hullCloud->push_back(p);
  }
  {
    pcl::PointXYZ p;
    p.x = 1;
    p.y = -1;
    p.z = -1;
    hullCloud->push_back(p);
    p.z = 1;
    hullCloud->push_back(p);
  }

  // setup hull filter
  pcl::ConvexHull<pcl::PointXYZ> cHull;
  cHull.setInputCloud(hullCloud);
  cHull.reconstruct(*hullPoints, hullPolygons);

  cropHullFilter.setHullIndices(hullPolygons);
  cropHullFilter.setHullCloud(hullPoints);
  //cropHullFilter.setDim(2); // if you uncomment this, it will work
  cropHullFilter.setCropOutside(false); // this will remove points inside the hull

  // create point cloud
  boost::shared_ptr<PointCloud> pc(new PointCloud());

  // a point inside the hull
  {
    pcl::PointXYZ p;
    p.x = 0;
    p.y = 0;
    p.z = 0;
    pc->push_back(p);
  }

  // and a point outside the hull
  {
    pcl::PointXYZ p;
    p.x = 10;
    p.y = 10;
    p.z = 10;
    pc->push_back(p);
  }


  for(size_t i=0; i < pc->size(); ++i)
  {
    std::cout << (*pc)[i] << std::endl;
  }

  //filter points
  std::cout << "Point cloud: " << std::endl;
  cropHullFilter.setInputCloud(pc);
  boost::shared_ptr<PointCloud> filtered(new PointCloud());
  cropHullFilter.filter(*filtered);

  std::cout << "Filtered point cloud: " << std::endl;
  for(size_t i=0; i < filtered->size(); ++i)
  {
    std::cout << (*filtered)[i] << std::endl;
  }


  return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions