Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CropHull 3d not cropping inside #1657

Open
carlosdcsantos opened this issue Jul 21, 2016 · 3 comments · May be fixed by #3883
Open

CropHull 3d not cropping inside #1657

carlosdcsantos opened this issue Jul 21, 2016 · 3 comments · May be fixed by #3883
Labels
kind: bug Type of issue module: filters needs: pr merge Specify why not closed/merged yet

Comments

@carlosdcsantos
Copy link

carlosdcsantos commented Jul 21, 2016

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;
}
@gtinchev
Copy link

This is correct - the issue exists and the proposed solution works. Could you perhaps make a PR?

@SergioRAgostinho
Copy link
Member

Please do guys 😬

@prmondal
Copy link

How can I get triangle indices for cropped cloud after cropping the cloud using crop_hull?

@SergioRAgostinho SergioRAgostinho added the needs: code review Specify why not closed/merged yet label Dec 10, 2017
watertown pushed a commit to piaggiofastforward/pcl that referenced this issue Jul 23, 2018
DaniilSNikulin pushed a commit to DaniilSNikulin/pcl that referenced this issue Apr 7, 2020
…udLibrary#1657)

* funciton applyFilter didn't clear output data before start adding new
point or indices

* issue PointCloudLibrary#1657: CropHull 3d not cropping inside.
[decision](piaggiofastforward@b8a8a2b)
@kunaltyagi kunaltyagi added kind: todo Type of issue module: filters needs: pr merge Specify why not closed/merged yet kind: bug Type of issue and removed needs: code review Specify why not closed/merged yet kind: todo Type of issue labels May 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug Type of issue module: filters needs: pr merge Specify why not closed/merged yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants