问题
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?
回答1:
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);
回答2:
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);
来源:https://stackoverflow.com/questions/45790828/remove-points-outside-defined-3d-box-inside-pcl-visualizer