PointCloudLibrary / PointCloudLibrary/pcl
CropHull 3d not cropping inside
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 4.7k
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 6
Description
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;
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in crop_hull.hpp around line 202 and inspect how crossings and crop_outside_ determine whether a point is emitted. Run the supplied C++ reproduction with the default 3D dimension and setCropOutside(false). Done means points inside the hull are removed while points outside remain, without breaking the existing 2D behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-vision
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100