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

FLARELocalReferenceFrameEstimation class added #1571

Merged
merged 11 commits into from
Nov 5, 2017

Conversation

aliosciapetrelli
Copy link
Contributor

Implementation of the Fast LocAl Reference framE algorithm for local reference frame estimation as described here:
A. Petrelli, L. Di Stefano,
"A repeatable and efficient canonical reference for surface matching",
3DimPVT, 2012

FLARE algorithm has been devised by the same authors of BOARD method (implemented by the BOARDLocalReferenceFrameEstimation class) and proved to be more repeatable and faster than BOARD.

List of modifications:

  • FLARELocalReferenceFrameEstimation class added
  • unit test for FLARELocalReferenceFrameEstimation class added
  • directedOrthogonalAxis, projectPointOnPlane, getAngleBetweenUnitVectors, randomOrthogonalAxis, normalDisambiguation and planeFitting methods of BOARDLocalReferenceFrameEstimation class
    moved to lrf_utils.hpp

@aliosciapetrelli
Copy link
Contributor Author

The pull request has been rebased and all the fixes has been squashed.

@SergioRAgostinho SergioRAgostinho added this to the pcl-1.9.0 milestone Jul 11, 2016
@SergioRAgostinho SergioRAgostinho added the needs: code review Specify why not closed/merged yet label Jul 11, 2016
@SergioRAgostinho
Copy link
Member

SergioRAgostinho commented Aug 18, 2016

Hi @aliosciapetrelli. Thanks for contributing this to the project. Sorry for the delay in providing feedback.

Tutorial (optional)

Although not required, it would be great if you could submit also a tutorial similar to this, briefly explaining the theoretical primer and showing a simple use case. It really helps to promote your contribution as users tend to explore the tutorials, not really the repository. :/

Once more, thanks for this 👍

@aliosciapetrelli
Copy link
Contributor Author

Hi Sérgio,
I'm very interested in promoting my algorithm to the community.
Following your advice, I'll work on a tutorial in the next days.

Regards,
Alioscia

On Thu, Aug 18, 2016 at 3:46 PM, Sérgio Agostinho notifications@github.com
wrote:

Hi @aliosciapetrelli https://github.com/aliosciapetrelli. Thanks for
contributing this to the project. Sorry for the delay in providing
feedback.

Tutorial (optional)

Although not required, it would be great if you could submit also a
tutorial similar to this, briefly explaining the theoretical primer and
showing a simple use case. It really helps to promote your contribution as
users tend to explore the tutorials, not really the repository. :/

Once more, thanks for this 👍


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#1571 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ARTHYaJGBDueiu1nizc9Dvmpg5wwLUa6ks5qhGIbgaJpZM4H71fB
.

@SergioRAgostinho
Copy link
Member

This was superseeded by #1614, but given the request for splitting the PR this might be a logical division

@taketwo
Copy link
Member

taketwo commented Jul 5, 2017

You are right, I think merging this PR would be a great starting point.

@aliosciapetrelli are you still interesting in contributing?

@aliosciapetrelli
Copy link
Contributor Author

Hi,
Sorry if I have not responded yet, but these days I'm very busy.
I have planned to start the commits this weekend.

@taketwo
Copy link
Member

taketwo commented Jul 6, 2017

Great to hear that you are still with us! So, as I said, let's work on merging this PR first. As far as I see, this PR is exactly the same as the first commit of the ReLOC pull request (#1614). Sergio already reviewed it there. It's somewhat inconvenient, but I would propose you to take into account those comments, but carry on the discussion here.

@taketwo
Copy link
Member

taketwo commented Jul 8, 2017

I had a look at the functions that you extracted from Board into a separate utils file. As I wrote before, I think they should rather be moved into appropriate places in existing PCL modules. And in fact, some of them are just duplicating functionality that already exists. Here is a list:

  • getAngleBetweenUnitVectors: we have a similar function already (getAngle3D) in "common/common.h". I think this one can be renamed and moved there becoming an overload.
  • planeFitting: implemented in "features/normal_3d.h"
  • normalDisambiguation: there is a similar in spirit function (flipNormalTowardsViewpoint) in "features/normal_3d.h", perhaps can move there
  • projectPointOnPlane: in "common/geometry.h" there is already project function which does the same
  • areEquals: this can be deleted, we have equal in "common/utils.h"
  • directedOrthogonalAxis and randomOrthogonalAxis: can not find anything similar. Perhaps can go to "common/geometry.h"? Or any better ideas?

/** \brief Get a pointer to the sampled_surface_ cloud dataset. */
inline PointCloudInConstPtr
getSearchSampledSurface() const
{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I understood correctly, I should simply replace "PointCloudInConstPtr" with "const PointCloudInConstPtr&".
But in this case, what's the difference with getSearchSurface () in Feature class? They seem equivalent to me.

Copy link
Member

@SergioRAgostinho SergioRAgostinho Jul 8, 2017

Choose a reason for hiding this comment

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

You we're mimicking something you saw in the base class, which is good, but it doesn't mean the base class is doing it right. The reason I ask for the const reference is because with it you can do both

const FLARELocalReferenceFrameEstimation<PointInT, PointOutT>::PointCloudInConstPtr& sampled_surface = flare.getSampledSurface (); //No copy of anything is made, no triggering of ref count
FLARELocalReferenceFrameEstimation<PointInT, PointOutT>::PointCloudInConstPtr sampled_surface = flare.getSampledSurface (); //A copy is made, ref count is triggered.

With the old signature you can only do the second one, because you can't bind a reference to an rvalue.

Basically you're giving an option to the caller to decide if he needs the copy or just the reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, fine.

/** \brief Get a pointer to the search method used for the extimation of x axis. */
inline KdTreePtr
getSearchMethodForSampledSurface () const
{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same comment as above but now related to getSearchMethod () to Feature class.

Copy link
Member

Choose a reason for hiding this comment

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

Same answer as above.

@SergioRAgostinho SergioRAgostinho added needs: author reply Specify why not closed/merged yet and removed needs: code review Specify why not closed/merged yet labels Jul 8, 2017
@aliosciapetrelli
Copy link
Contributor Author

How should I proceed with the virtual keyword?
I agree with @taketwo that it makes the code more readable.
Moreover, in the future migration, the presence of the virtual keyword could make easier to identify where to place the override keyword.

Nevertheless, I'm ready to commit the changes.

@SergioRAgostinho
Copy link
Member

Go with @taketwo 's pointers on this one.

@taketwo
Copy link
Member

taketwo commented Jul 9, 2017

Moreover, in the future migration, the presence of the virtual keyword could make easier to identify where to place the override keyword.

... there is also a special warning for this, so the compiler will tell us.

@SergioRAgostinho
Copy link
Member

SergioRAgostinho commented Jul 12, 2017

I'm not sure if you're done already but you need to ditch that merge commit from master you just did. What you need to do is rebase your FLARE original commit to the tip of master. This is a good read for that https://www.atlassian.com/git/tutorials/rewriting-history

@aliosciapetrelli
Copy link
Contributor Author

I'm not familiar with Git, specially with rebasing, so I need to study the topic.

@SergioRAgostinho
Copy link
Member

No worries, take your time. Don't forget to backup everything and try it first on a copy of your repo.

Some quick pointers:

  • with rebase -i you can completely delete your last merge commit from master
  • then you'll need to invoke your rebase against upstream/master
  • confirm if things went as intended with git log. Your commit should be right on top of the last commit of upstream/master
  • if things are ok then do a git push -f <your fork>

@aliosciapetrelli
Copy link
Contributor Author

In the end, is it better if the pull request will result in a unique commit (with the initial changes together with the ones after the review) or in two different commits (one for the initial changes and another for the review)?

@SergioRAgostinho
Copy link
Member

Most likely it will be a single commit. We'll squash everything after all reviews and corresponding changes are committed.

aliosciapetrelli and others added 2 commits July 17, 2017 22:35
- Add FLARELocalReferenceFrameEstimation class
- Add unit test for FLARELocalReferenceFrameEstimation class
- Add LRF_utils.h
- Add LRF_utils.cpp
- Add directedOrthogonalAxis, projectPointOnPlane in lrf_utils
- getAngleBetweenUnitVectors, randomOrthogonalAxis, normalDisambiguation
and planeFitting methods of BOARDLocalReferenceFrameEstimation class
moved to lrf_utils.hpp
@taketwo taketwo added needs: author reply Specify why not closed/merged yet and removed needs: code review Specify why not closed/merged yet labels Aug 7, 2017
@SergioRAgostinho
Copy link
Member

SergioRAgostinho commented Aug 7, 2017 via email

@aliosciapetrelli
Copy link
Contributor Author

I think it's ok now.

@SergioRAgostinho SergioRAgostinho added needs: code review Specify why not closed/merged yet and removed needs: author reply Specify why not closed/merged yet labels Oct 31, 2017
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.

Sorry for the delay. I think this is my last round. Everything are minor comments.

project (point, plane_origin, plane_normal, projection);
projected_as_unit_vector = projection - plane_origin;
projected_as_unit_vector.normalize ();
}
Copy link
Member

Choose a reason for hiding this comment

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

May I advise to simply return projected_as_unit_vectoras the function return value. My comment is exploiting something called Return Value Optimization and it would allow initializing Eigen::Vector3f variables from the output of this function.

}

rand_ortho_axis.normalize ();
}
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 regarding RVO.

}
}

if(normal_mean.isZero())
Copy link
Member

Choose a reason for hiding this comment

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

You missed spacing here.

{
const PointNT& cur_pt = normal_cloud[normal_indices[i]];

if (pcl::isFinite(cur_pt))
Copy link
Member

Choose a reason for hiding this comment

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

Spacing here.

ne.setViewPoint (1, 1, 10);
ne.setInputCloud (cloud);
ne.setSearchMethod (tree);
ne.setIndices (indices_ptr);
Copy link
Member

Choose a reason for hiding this comment

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

Do you need to set the indices here? The default behavior if you don't set the indices is to use all the points anyway. The indices are just used to allow you to mask specifics points of your input.

typedef typename pcl::PointCloud<SignedDistanceT> PointCloudSignedDistance;
typedef typename PointCloudSignedDistance::Ptr PointCloudSignedDistancePtr;

typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr;
Copy link
Member

Choose a reason for hiding this comment

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

This definition already exists in pcl::Feature so replace it with

using typename Feature<PointInT, PointOutT>::PointCloudInConstPtr;

typedef boost::shared_ptr<FLARELocalReferenceFrameEstimation<PointInT, PointNT, PointOutT> > Ptr;
typedef boost::shared_ptr<const FLARELocalReferenceFrameEstimation<PointInT, PointNT, PointOutT> > ConstPtr;

typedef typename pcl::search::Search<PointInT>::Ptr KdTreePtr;
Copy link
Member

Choose a reason for hiding this comment

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

This definition also exist in pcl::Featureso apply the same method as above.


/** \brief Empty destructor */
virtual
~FLARELocalReferenceFrameEstimation () {}
Copy link
Member

Choose a reason for hiding this comment

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

You don't need to declare this destructor (even if it's virtual). See https://stackoverflow.com/questions/2198379/are-virtual-destructors-inherited#2198400

Please delete it.


Eigen::Vector3f best_margin_point;

float radius2 = tangent_radius_ * tangent_radius_;
Copy link
Member

Choose a reason for hiding this comment

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

const


float radius2 = tangent_radius_ * tangent_radius_;

float margin_distance2 = margin_thresh_ * margin_thresh_ * radius2;
Copy link
Member

Choose a reason for hiding this comment

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

const

@SergioRAgostinho SergioRAgostinho added needs: author reply Specify why not closed/merged yet and removed needs: code review Specify why not closed/merged yet labels Nov 1, 2017
@aliosciapetrelli
Copy link
Contributor Author

Done. It should be ok now.

Before you start any review of #1614, it could be better if I perform a review of all the code on the basis of the suggestions you gave me in this discussion. It should speed up the future changes and discussion of #1614.

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.

Some remnant code which stayed after indices stop being used.

typedef pcl::PointCloud<pcl::PointXYZ>::Ptr PointCloudPtr;

PointCloudPtr cloud;
std::vector<int> indices;
Copy link
Member

Choose a reason for hiding this comment

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

I this is now no longer needed I think.


indices.resize (cloud->points.size ());
for (size_t i = 0; i < indices.size (); ++i)
indices[i] = static_cast<int> (i);
Copy link
Member

Choose a reason for hiding this comment

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

Everything pertaining to indices can be deleted I think.

@SergioRAgostinho
Copy link
Member

That would be super 👍 Thanks for that.

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.

Note to maintainers: squash before merge.

Copy link
Member

@taketwo taketwo left a comment

Choose a reason for hiding this comment

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

Hi, I pointed some more style issues. Once those are fixed, I'm ready to squash-merge.

}

//set z_axis as the normal of index point
fitted_normal = (*normals_)[index].getNormalVector3fMap();
Copy link
Member

Choose a reason for hiding this comment

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

Missing space

else
{
float plane_curvature;
normal_estimation_.computePointNormal(*surface_, neighbours_indices, fitted_normal(0), fitted_normal(1), fitted_normal(2), plane_curvature);
Copy link
Member

Choose a reason for hiding this comment

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

Missing spaces

int best_shape_index = -1;

Eigen::Vector3f best_margin_point;

Copy link
Member

Choose a reason for hiding this comment

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

Empty line here and some more below, do we need them?

{
PCL_ERROR(
"[pcl::%s::computeFeature] Error! Search method set to k-neighborhood. Call setKSearch(0) and setRadiusSearch( radius ) to use this class.\n",
getClassName().c_str());
Copy link
Member

Choose a reason for hiding this comment

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

Missing spaces

}
}

if(normal_mean.isZero ())
Copy link
Member

Choose a reason for hiding this comment

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

Missing space

@taketwo taketwo merged commit 8182d25 into PointCloudLibrary:master Nov 5, 2017
@taketwo taketwo removed the needs: author reply Specify why not closed/merged yet label Nov 5, 2017
@taketwo
Copy link
Member

taketwo commented Nov 5, 2017

One and a half years, 83 comments, 11 commits, and we are finally done. Thanks everyone for the effort!

@SergioRAgostinho
Copy link
Member

Woohoo 🙌

@SergioRAgostinho
Copy link
Member

It might be worth to write a post to the mailing list to warn that there's a new Feature in town.

UnaNancyOwen pushed a commit to UnaNancyOwen/pcl that referenced this pull request Nov 24, 2017
Add implementation of the Fast LocAl Reference framE (FLARE) algorithm
aliosciapetrelli pushed a commit to aliosciapetrelli/pcl that referenced this pull request Jan 20, 2018
This reverts commit 1224939.

As FLARELocalReferenceFrameEstimation class has been already added by pull request PointCloudLibrary#1571
@taketwo taketwo added changelog: new feature Meta-information for changelog generation module: features labels Sep 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: new feature Meta-information for changelog generation module: features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants