19 #include <pcl/filters/voxel_grid.h> 20 #include <pcl/filters/crop_box.h> 21 #include <pcl/filters/statistical_outlier_removal.h> 22 #include <pcl/filters/radius_outlier_removal.h> 23 #include <pcl/filters/extract_indices.h> 24 #include <pcl/common/angles.h> 25 #include <pcl/segmentation/sac_segmentation.h> 26 #include <pcl/segmentation/segment_differences.h> 28 Filter::Filter(
double leaf_size)
30 leaf_size_ = leaf_size;
33 given_center_ =
false;
36 Filter::Filter(
double leaf_size,
double noise_threshold,
double floor_threshold)
38 leaf_size_ = leaf_size;
39 noise_threshold_ = noise_threshold;
40 floor_threshold_ = floor_threshold;
41 given_center_ =
false;
44 void Filter::setLeafSize(
double leaf_size)
46 leaf_size_ = leaf_size;
49 void Filter::setCloudCenter(Eigen::Vector3f cloud_center)
51 cloud_center_[0] = cloud_center[0];
52 cloud_center_[1] = cloud_center[1];
53 cloud_center_[2] = cloud_center[2];
57 void Filter::setNoiseThreshold(
double noise_th)
59 noise_threshold_ = noise_th;
62 void Filter::setFloorThreshold(
double floor_th)
64 floor_threshold_ = floor_th;
67 void Filter::run(PointCloudRGB::Ptr cloud, PointCloudRGB::Ptr cloud_filtered)
70 pcl::copyPointCloud(*cloud, *cloud_filtered);
73 if (floor_threshold_ > 0)
74 filterFloor(cloud_filtered, cloud_filtered);
77 if (noise_threshold_ > 0)
78 filterNoise(cloud_filtered, cloud_filtered);
81 void Filter::outlierRemove(PointCloudRGB::Ptr cloud, PointCloudRGB::Ptr cloud_filtered)
84 pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> outlier_filter;
85 outlier_filter.setInputCloud(cloud);
86 outlier_filter.setMeanK(50);
87 outlier_filter.setStddevMulThresh(1.0);
88 outlier_filter.filter(*cloud_filtered);
91 void Filter::downsampleCloud(PointCloudRGB::Ptr cloud, PointCloudRGB::Ptr cloud_downsampled)
93 ROS_INFO(
"Downsample cloud with leaf_size : %f", leaf_size_);
95 ROS_INFO(
"Pointcloud resolution before downsampling: %f", res);
97 const Eigen::Vector4f downsampling_leaf_size(leaf_size_, leaf_size_, leaf_size_, 0.0f);
98 pcl::VoxelGrid<pcl::PointXYZRGB> downsampling_filter;
99 downsampling_filter.setInputCloud(cloud);
100 downsampling_filter.setLeafSize(downsampling_leaf_size);
101 downsampling_filter.filter(*cloud_downsampled);
104 ROS_INFO(
"Pointcloud resolution after downsampling: %f", res);
107 void Filter::filterNoise(PointCloudRGB::Ptr cloud, PointCloudRGB::Ptr cloud_filtered)
109 pcl::CropBox<pcl::PointXYZRGB> boxFilter;
112 pcl::compute3DCentroid(*cloud, cloud_center_);
114 Eigen::Vector3f boxTranslatation;
115 boxTranslatation[0] = cloud_center_[0];
116 boxTranslatation[1] = cloud_center_[1];
117 boxTranslatation[2] = cloud_center_[2];
118 ROS_INFO(
"Point cloud center: (%f,%f,%f)", cloud_center_[0], cloud_center_[1], cloud_center_[2]);
119 ROS_INFO(
"Filter noise with threshold: (%f,%f,%f)", noise_threshold_, noise_threshold_, noise_threshold_/5);
121 boxFilter.setTranslation(boxTranslatation);
122 boxFilter.setMin(Eigen::Vector4f(-noise_threshold_, -noise_threshold_, -noise_threshold_/5, 1.0));
123 boxFilter.setMax(Eigen::Vector4f(noise_threshold_, noise_threshold_, noise_threshold_/5, 1.0));
124 boxFilter.setInputCloud(cloud);
125 boxFilter.filter(*cloud_filtered);
129 ROS_ERROR(
"Unable to filter noise. Unfiltered cloud");
130 pcl::copyPointCloud(*cloud, *cloud_filtered);
134 void Filter::filterFloor(PointCloudRGB::Ptr cloud, PointCloudRGB::Ptr cloud_filtered)
137 bool displace =
false;
138 for (
size_t i = 0; i < cloud->points.size() && !displace; i++)
140 if (cloud->points[i].z < 0)
149 Eigen::Vector3f axis(0, 0, 1);
151 pcl::SACSegmentation<pcl::PointXYZRGB> seg;
153 seg.setEpsAngle(pcl::deg2rad(1.0));
154 seg.setOptimizeCoefficients(
true);
155 seg.setModelType(pcl::SACMODEL_PERPENDICULAR_PLANE);
156 seg.setMethodType(pcl::SAC_RANSAC);
157 seg.setDistanceThreshold(floor_threshold_);
158 seg.setInputCloud(cloud);
160 pcl::ModelCoefficients coeff;
161 pcl::PointIndices floor;
162 seg.segment(floor, coeff);
164 if(floor.indices.size() == 0)
166 ROS_ERROR(
"Unable to find floor. Unfiltered cloud");
167 pcl::copyPointCloud(*cloud, *cloud_filtered);
171 Filter::extractIndicesNegative(cloud, cloud_filtered,
172 boost::make_shared<std::vector<int>>(floor.indices));
176 void Filter::removeFromCloud(PointCloudRGB::Ptr input_cloud,
177 PointCloudRGB::Ptr substract_cloud,
179 PointCloudRGB::Ptr cloud_filtered)
181 ROS_INFO(
"Difference from segment with threshold: %f", threshold);
182 pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(
new pcl::search::KdTree<pcl::PointXYZRGB>);
183 pcl::SegmentDifferences<pcl::PointXYZRGB> segment;
184 segment.setInputCloud(input_cloud);
185 segment.setTargetCloud(substract_cloud);
186 segment.setSearchMethod(tree);
187 segment.setDistanceThreshold(threshold);
188 segment.segment(*cloud_filtered);
191 void Filter::extractIndicesNegative(PointCloudRGB::Ptr cloud_in,
192 PointCloudRGB::Ptr cloud_out,
193 pcl::IndicesPtr indices)
195 pcl::ExtractIndices<pcl::PointXYZRGB> extract_indices_filter;
196 extract_indices_filter.setInputCloud(cloud_in);
197 extract_indices_filter.setIndices(indices);
198 extract_indices_filter.setNegative(
true);
199 extract_indices_filter.filter(*cloud_out);
202 void Filter::extractIndices(PointCloudRGB::Ptr cloud_in,
203 PointCloudRGB::Ptr cloud_out,
204 pcl::IndicesPtr indices)
206 pcl::ExtractIndices<pcl::PointXYZRGB> extract_indices_filter;
207 extract_indices_filter.setInputCloud(cloud_in);
208 extract_indices_filter.setIndices(indices);
209 extract_indices_filter.filter(*cloud_out);
212 void Filter::extractIndices(PointCloudNormal::Ptr normals_in,
213 PointCloudNormal::Ptr normals_out,
214 pcl::IndicesPtr indices)
216 pcl::ExtractIndices<pcl::Normal> extract_indices_filter;
217 extract_indices_filter.setInputCloud(normals_in);
218 extract_indices_filter.setIndices(indices);
219 extract_indices_filter.filter(*normals_out);
static bool isValidCloud(PointCloudXYZ::Ptr cloud)
Check whether cloud contains data and is not empty.
static void translateCloud(PointCloudRGB::Ptr cloud_in, PointCloudRGB::Ptr cloud_out, double x_offset=0, double y_offset=0, double z_offset=0)
Apply translation to Cloud. Values given in [m].
static double computeCloudResolution(PointCloudXYZ::Ptr cloud)
Obtain the resolution of the cloud.