简体   繁体   中英

Remove points outside defined 3D box inside PCL visualizer

In a given point cloud, I want to remove all the points which are less than min and greater than max for all x , y and z direction. Below is the sample code:

#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/pcl_visualizer.h>

// Define min and max for X, Y and Z
float minX = -0.1, minY = -0.5, minZ = -2.5;
float maxX = +0.1, maxY = +0.5, maxZ = +2.5;

int main (int argc, char** argv)
{
    pcl::visualization::PCLVisualizer viewer("Cloud Viewer");

    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr body (new pcl::PointCloud<pcl::PointXYZRGBA>);
    pcl::io::loadPCDFile ("body.pcd", *body);

    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr bodyFiltered (new pcl::PointCloud<pcl::PointXYZRGBA>);

    pcl::PassThrough<pcl::PointXYZRGBA> filter;
    filter.setInputCloud (body);
    filter.setFilterFieldName ("x");
    filter.setFilterLimits (minX, maxX);
    filter.setFilterFieldName ("y");
    filter.setFilterLimits (minY, maxY);
    filter.setFilterFieldName ("z");
    filter.setFilterLimits (minZ, maxZ);
    filter.filter (*bodyFiltered);

    viewer.addPointCloud (bodyFiltered,"body");
    viewer.spin();
    return 0;
}

It seems that only last filter is being applied. Any solution, please?

What about using pcl::CropBox ? ( documentation )

pcl::CropBox<pcl::PointXYZRGBA> boxFilter;
boxFilter.setMin(Eigen::Vector4f(minX, minY, minZ, 1.0));
boxFilter.setMax(Eigen::Vector4f(maxX, maxY, maxZ, 1.0));
boxFilter.setInputCloud(body);
boxFilter.filter(*bodyFiltered);

To know why this filter takes Vector4f (and not Vector3f) see the comments below and this question .

You have found what the documentation makes clear.

PassThrough passes points in a cloud based on constraints for one particular field of the point type.

For multiple fields a different filter should be used, such as ConditionalRemoval

The following is untested, but it'll be something like this.

pcl::ConditionOr<PointT>::Ptr range_cond (new pcl::ConditionOr<PointT> ()); 
range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("x", pcl::ComparisonOps::GT, minX)));
range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("x", pcl::ComparisonOps::LT, maxX)));
range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("y", pcl::ComparisonOps::GT, minY)));
range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("y", pcl::ComparisonOps::LT, maxY)));
range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("z", pcl::ComparisonOps::GT, minZ)));
range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("z", pcl::ComparisonOps::LT, maxZ)));

pcl::ConditionalRemoval<PointT> range_filt;
range_filt.setInputCloud(body);
range_filt.setCondition (range_cond);
range_filt.filter(*bodyFiltered);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM