Skip to content
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

Modularize euclidean clustering #4268

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

shrijitsingh99
Copy link
Contributor

@shrijitsingh99 shrijitsingh99 commented Jul 13, 2020

Continuing discussion from shrijitsingh99#4

@kunaltyagi kunaltyagi added changelog: enhancement Meta-information for changelog generation module: segmentation needs: more work Specify why not closed/merged yet labels Jul 13, 2020
@shrijitsingh99 shrijitsingh99 added the priority: gsoc Reason for prioritization label Jul 13, 2020
@kunaltyagi
Copy link
Member

I recommend "Refined GitHub" plugin to move the close button away from comment button

@kunaltyagi kunaltyagi added the needs: pr merge Specify why not closed/merged yet label Jul 13, 2020
@kunaltyagi
Copy link
Member

Depends on #4269

@shrijitsingh99
Copy link
Contributor Author

I recommend "Refined GitHub" plugin to move the close button away from comment button

This plugin is pretty cool and highly useful.
Though this time I encountered a strange GitHub bug (isaacs/github#750). The PR wasn't updating with my latest commits for some reason 😕

@kunaltyagi kunaltyagi removed the needs: pr merge Specify why not closed/merged yet label Jul 13, 2020
Copy link
Member

@SergioRAgostinho SergioRAgostinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial (3/4)

segmentation/include/pcl/segmentation/extract_clusters.h Outdated Show resolved Hide resolved
segmentation/include/pcl/segmentation/extract_clusters.h Outdated Show resolved Hide resolved
Comment on lines -61 to +62
template<typename T> void
ignore(const T&)
template<typename ...T> void
ignore(const T&...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merged to master in the meantime

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will rebase, once issues are resolved.

examples/segmentation/example_extract_clusters_normals.cpp Outdated Show resolved Hide resolved
* \param min_pts_per_cluster minimum number of points that a cluster may contain (default: 1)
* \param max_pts_per_cluster maximum number of points that a cluster may contain (default: max int)
* \warning It is assumed that that the tree built on the same indices and cloud as passed here,
* if that is not the case then things can go very wrong. For speed reasons, we only check the sizes and not the content
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reword to be in a passive voice. This example is not quite right but should point you in the correct direction:

The cloud/indices being passed here must be the same ones used to build the tree. PCL warns if the error is explicit (sizes are equal), but doesn't check for deep equality in the interest of performance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error

segmentation/include/pcl/segmentation/extract_clusters.h Outdated Show resolved Hide resolved
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** \brief Decompose a region of space into clusters based on the Euclidean distance between points
* \param cloud the point cloud message
* \param additional_filter_criteria functor which is used as an additonal criteria that all points being added to the cluster must satisfy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the constraints on the functor? Does []{return true;} suffice? Will [](MyClass ...A){return AnotherClass{A...};} work?

Tighten the interface appropriately:

  • enough leeway for user
  • no need to read the documentation based on error message

Copy link
Contributor Author

@shrijitsingh99 shrijitsingh99 Jul 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Pick it up form

template <typename PointT, typename Function>
constexpr static bool is_functor_for_filter_v =
pcl::is_invocable_r_v<bool,
Function,
const pcl::remove_cvref_t<pcl::PointCloud<PointT>>&,
pcl::index_t>;

Slighlty off topic, whats the reason for using pcl::remove_cvref_t and then adding const and &?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a brain-fart. The remove_cvref was meant for something else, but in refactoring from old version to the newer simplified checker implementation, it managed to slip through.

segmentation/include/pcl/segmentation/extract_clusters.h Outdated Show resolved Hide resolved
constexpr static bool is_functor_for_additional_filter_criteria_v =
pcl::is_invocable_r_v<bool,
Function,
const pcl::remove_cvref_t<pcl::PointCloud<PointT>>&,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With const and reference collapsing rules, isn't this the same as const remove_volatile_t<pcl::PointCloud<PointT>>&,?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. Which leads to the next question, why do you care if the user supplies a type which is volatile?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's more about remove_cvref_t being used to strip const and reference qualifiers, and nobody gives a thought about volatile. As far as I'm concerned I wouldn't consider volatile in such a case and would go with const pcl::PointCloud<PointT>&? directly.

Copy link
Member

@kunaltyagi kunaltyagi Jul 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just chiming in, being the author of the original snippet this is copied from: it's a mistake from when I was taking in the functor itself (typename FunctorT) and needed this to get arguments and constrain the input to const PointCloud<PointT>& (no volatile allowed). But the design changed, and got simplified thanks to the reviews but this managed to slip in.

We know the type here, and remove_X is doing nothing of value here

Copy link
Member

@SergioRAgostinho SergioRAgostinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial (2/4)

Function,
const pcl::remove_cvref_t<pcl::PointCloud<PointT>>&,
pcl::index_t,
const pcl::remove_cvref_t<Indices>&,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment here.

constexpr static bool is_functor_for_additional_filter_criteria_v =
pcl::is_invocable_r_v<bool,
Function,
const pcl::remove_cvref_t<pcl::PointCloud<PointT>>&,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. Which leads to the next question, why do you care if the user supplies a type which is volatile?

Comment on lines +76 to +80
template <typename PointT, typename FunctorT> void
extractEuclideanClusters(
ConstCloudIterator<PointT> &it, const PointCloud<PointT> &cloud, FunctorT additional_filter_criteria,
const typename search::Search<PointT>::Ptr &tree, float tolerance, std::vector<PointIndices> &clusters,
unsigned int min_pts_per_cluster = 1, unsigned int max_pts_per_cluster = std::numeric_limits<int>::max())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to move the implementation of this method to the .hpp file. There's no solid reason to keep it in the .h file

*/
template <typename PointT, typename FunctorT> void
extractEuclideanClusters(
ConstCloudIterator<PointT> &it, const PointCloud<PointT> &cloud, FunctorT additional_filter_criteria,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not liking this pattern where you pass the cloud iterator as an argument, but still pass the whole point cloud as well to the function. Please change to the following.

extractEuclideanClusters(const PointCloud<PointT> &cloud, const Indices &indices, [...]);

Overloads which don't have indices in their function signature, should supply empty indices to this method. You call the appropriate constructor for CloudIterator after checking if indices is empty or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the cloudIterator is not well engineered enough for this.

Let's kill the idea of using the cloudIterator in public interface and hide it. It's still useful for removing common code, but beyond that, cloud is needed for size check as well as passing to the user's lambda

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overloads which don't have indices in their function signature, should supply empty indices to this method

That's a problematic behavior chain in pipelines. If after filtering/previous segmentation my indices became empty, now this clustering would run on the entire point cloud 😱

@stale
Copy link

stale bot commented Aug 16, 2020

Marking this as stale due to 30 days of inactivity. Commenting or adding a new commit to the pull request will revert this.

@stale stale bot added the status: stale label Aug 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: enhancement Meta-information for changelog generation module: segmentation needs: more work Specify why not closed/merged yet priority: gsoc Reason for prioritization status: stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants