-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix the removed indices of UniformSampling #2022
Fix the removed indices of UniformSampling #2022
Conversation
Hi. Can you give provide more details about the behavior you're trying to correct with this PR? I.e., what was your use case with this class, which was failing with the current implementation. |
I was using the removed indices to filter an organized point cloud, as this class returns an unorganized cloud. What I noticed was that |
I had a look at your suggested changes:
What is valid though is |
bc6c2b7
to
1fb8e32
Compare
We are indeed looping the entire index vector but we're always only considering
Correct, unfortunately I don't see a better way to set the
This was indeed incorrect from my side and is fixed in the latest commits.
Indeed. To clarify my point, I have added two unit test, both which fail on master. |
Your explanation didn't really make sense to me, because I went digging for the issue myself and found the bug. The issue was that we were not adding the points in the condition that their distance was bigger than the one for the index already stored on the leaf. The snippet below should help to clarify my lousy explanation. Your tests (thank you for writing them btw), are running green. // First pass: build a set of leaves with the point index closest to the leaf center
for (size_t cp = 0; cp < indices_->size (); ++cp)
{
[...]
// Check to see if this point is closer to the leaf center than the previous one we saved
float diff_cur = (input_->points[(*indices_)[cp]].getVector4fMap () - ijk.cast<float> ()).squaredNorm ();
float diff_prev = (input_->points[leaf.idx].getVector4fMap () - ijk.cast<float> ()).squaredNorm ();
// If current point is closer, copy its index instead
if (Filter<PointT>::extract_removed_indices_)
Filter<PointT>::removed_indices_->push_back (diff_cur < diff_prev ? leaf.idx : (*indices_)[cp]);
if (diff_cur < diff_prev)
leaf.idx = (*indices_)[cp];
}
// Second pass: go over all leaves and copy data
output.points.resize (leaves_.size ());
int cp = 0;
[...] This was the test I created to trace the issue, because loading a 100k pointcloud is not really tractable for a human 😅 TEST (Full, Uniform_Sampling)
{
// Construct point cloud
PointCloud<PointXYZ>::Ptr simple (new PointCloud<PointXYZ>);
simple->push_back (PointXYZ (0, 0, 0));
simple->push_back (PointXYZ (0, 0, 1));
simple->push_back (PointXYZ (0, 0, .99));
simple->push_back (PointXYZ (0, 0, .98));
simple->push_back (PointXYZ (0, 1, 0));
simple->push_back (PointXYZ (0, 1, 1));
simple->push_back (PointXYZ (1, 0, 0));
simple->push_back (PointXYZ (1, 0, 1));
simple->push_back (PointXYZ (1, 1, 0));
simple->push_back (PointXYZ (1, 1, 1));
simple->is_dense = true;
const bool keep_remove_indices = true;
UniformSampling<PointXYZ> us (keep_remove_indices);
us.setInputCloud (simple);
us.setRadiusSearch (0.5);
PointCloud<PointXYZ>::Ptr cloud_filtered (new PointCloud<PointXYZ> ());
us.filter (*cloud_filtered);
const IndicesConstPtr& remove_indices = us.getRemovedIndices ();
EXPECT_EQ(remove_indices->size () + cloud_filtered->points.size (),
simple->points.size ());
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per my previous commentary.
Apologies for my absence. Your proposed fix seems indeed the better way to go. Wrt to your proposed test, the expected |
I don't understand what this refers to. After reading your comment regarding the lack of intuition of radius search parameter, I went digging again to understand the role it plays and in the source code it is used to define the leaf size. So currently |
This ensures that all removed indices are set and not only those of the indices that are visited. Ref
1fb8e32
to
e8e0f04
Compare
I wanted to extend your unit test to not only test the number of removed indices, but the algorithm itself. In your test I would expect that only one of the three points |
Agree about the irrelevance of search radius. What about deprecating |
That is definitely weird... According to the comments in the code, only the point closest to the leaf center should be preserved. I'm assuming the leaf center in this case to be at (0.25 , 0.25, 0.75) which means that only (0, 0, .98) should be preserved. Is the leaf center somewhere else?
Agreed. I think the term leaf size is also used for instance in the voxel grid filter. |
This pull request has been automatically marked as stale because it hasn't had Come back whenever you have time. We look forward to your contribution. |
This pull request has been automatically marked as stale because it hasn't had Come back whenever you have time. We look forward to your contribution. |
This pull request has been automatically marked as stale because it hasn't had Come back whenever you have time. We look forward to your contribution. |
This ensures that all removed indices are set and not only those of the indices that are visited.