diff --git a/filters/src/radius_outlier_removal.cpp b/filters/src/radius_outlier_removal.cpp index 0cd628bc9ca..600d1cc37da 100644 --- a/filters/src/radius_outlier_removal.cpp +++ b/filters/src/radius_outlier_removal.cpp @@ -106,9 +106,10 @@ pcl::RadiusOutlierRemoval::applyFilter (PCLPointCloud2 &out { //if(cp%log_step == 0) // PCL_DEBUG ("[pcl::%s::applyFilter] Iteration %i of %lu\n", getClassName ().c_str (), cp, indices_->size()); - int k = searcher_->radiusSearch ((*indices_)[cp], search_radius_, nn_indices, nn_dists); + int k = searcher_->radiusSearch( + (*indices_)[cp], search_radius_, nn_indices, nn_dists, min_pts_radius_ + 1); // Check if the number of neighbors is larger than the user imposed limit - if (k < min_pts_radius_) + if (k <= min_pts_radius_) { if (extract_removed_indices_) { @@ -215,7 +216,8 @@ pcl::RadiusOutlierRemoval::applyFilter (Indices &indices) { // Perform the radius search // Note: k includes the query point, so is always at least 1 - int k = searcher_->radiusSearch (idx, search_radius_, nn_indices, nn_dists); + int k = searcher_->radiusSearch( + idx, search_radius_, nn_indices, nn_dists, min_pts_radius_ + 1); // Points having too few neighbors are outliers and are passed to removed indices // Unless negative was set, then it's the opposite condition diff --git a/test/filters/test_filters.cpp b/test/filters/test_filters.cpp index ed02e96c695..17de73e483d 100644 --- a/test/filters/test_filters.cpp +++ b/test/filters/test_filters.cpp @@ -1585,7 +1585,7 @@ TEST (RadiusOutlierRemoval, Filters) RadiusOutlierRemoval outrem2; outrem2.setInputCloud (cloud_blob); outrem2.setRadiusSearch (0.02); - outrem2.setMinNeighborsInRadius (15); + outrem2.setMinNeighborsInRadius (14); outrem2.filter (cloud_out2); fromPCLPointCloud2 (cloud_out2, cloud_out); @@ -1616,7 +1616,7 @@ TEST (RadiusOutlierRemoval, Filters) RadiusOutlierRemoval outrem2_(true); outrem2_.setInputCloud (cloud_blob); outrem2_.setRadiusSearch (0.02); - outrem2_.setMinNeighborsInRadius (15); + outrem2_.setMinNeighborsInRadius (14); outrem2_.filter (cloud_out2); fromPCLPointCloud2 (cloud_out2, cloud_out); @@ -2579,6 +2579,49 @@ TEST (VoxelGridOcclusionEstimation, Filters) } } +///////////////////////////////////////////////// +TEST(RadiusOutlierRemovalPCLPointCloud2, Filters) +{ + // Test for the issue #2816. Both implementations must be true + PointCloud::Ptr pc_in(new PointCloud); + pc_in->push_back(PointXYZ(1.f, 0.f, 0.f)); + pc_in->push_back(PointXYZ(2.f, 0.f, 0.f)); + pc_in->push_back(PointXYZ(3.f, 0.f, 0.f)); + + PCLPointCloud2::Ptr pc2_in(new PCLPointCloud2); + toPCLPointCloud2(*pc_in, *pc2_in); + + // Template implementation + { + RadiusOutlierRemoval filter; + filter.setInputCloud(pc_in); + filter.setRadiusSearch(1.1); + filter.setMinNeighborsInRadius(2); + PointCloud pc_out; + filter.filter(pc_out); + ASSERT_EQ(pc_out.size(), 1); + EXPECT_NEAR(pc_out[0].x, 2.f, 1e-4f); + EXPECT_NEAR(pc_out[0].y, 0.f, 1e-4f); + EXPECT_NEAR(pc_out[0].z, 0.f, 1e-4f); + } + + // PCLPointCloud2 implementation should give the same result + { + RadiusOutlierRemoval filter; + filter.setInputCloud(pc2_in); + filter.setRadiusSearch(1.1); + filter.setMinNeighborsInRadius(2); + PCLPointCloud2 pc2_out; + filter.filter(pc2_out); + PointCloud pc_out; + fromPCLPointCloud2(pc2_out, pc_out); + ASSERT_EQ(pc_out.size(), 1); + EXPECT_NEAR(pc_out[0].x, 2.f, 1e-4f); + EXPECT_NEAR(pc_out[0].y, 0.f, 1e-4f); + EXPECT_NEAR(pc_out[0].z, 0.f, 1e-4f); + } +} + /* ---[ */ int main (int argc, char** argv)