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

Frontend segmentation components #23

Merged
merged 58 commits into from
Jul 20, 2024
Merged

Frontend segmentation components #23

merged 58 commits into from
Jul 20, 2024

Conversation

DamienGilliard
Copy link
Collaborator

@DamienGilliard DamienGilliard commented May 29, 2024

This PR concerns the segmentation of the scan. We use the 3d model to identify the pieces we need to segment. It introduces both the cpp backend and components for:

  • basic normal based segmentation
  • CAD-based segmentation

@DamienGilliard
Copy link
Collaborator Author

Proposed strategy for additive:

Capture d’écran 2024-06-01 à 14 16 18

@9and3
Copy link
Contributor

9and3 commented Jun 6, 2024

thanks for the proposal @DamienGilliard ! 🚀

my questions/doubts:

  • are you sure about the recursive registration to the scan, might be time consuming but especially not robust (?)
  • what about stop to global+refine and segmenting the cloud by normals (e.g. via cilantro) and than do a box search with the elements of the CAD model to find if the center of the clustes lies inside (or something similar) ?

@DamienGilliard
Copy link
Collaborator Author

Thanks for the reply !

I share your doubts about the recursive registration, i will soon know if it works sufficiently well (computation time wise, and accuracy wise)

For the second point, the reason is that planar surfaces in the scan can be the result of different pieces combined. This means that plane segmentation is not sufficient to get the point clouds of each piece. Do you agree ? I might be missing something ;)

@9and3
Copy link
Contributor

9and3 commented Jun 7, 2024

For the second point, the reason is that planar surfaces in the scan can be the result of different pieces combined. This means that plane segmentation is not sufficient to get the point clouds of each piece. Do you agree

Yes you are right indeed. Got no solutions for that though..

@9and3 9and3 marked this pull request as draft June 12, 2024 11:25
@DamienGilliard
Copy link
Collaborator Author

This branch has now been cleaned and contains the implementation of the initial segmentation. Branch(es) of this branch will contain the further implementation of the "semantic" segmentation.
Capture d'écran 2024-06-23 124431

Copy link
Contributor

Choose a reason for hiding this comment

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

NormalBasedSegmentation would not be more appropiate? Why "Smooth"? @DamienGilliard

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed. I used smooth because it looks for breaks in the normals to segment, and thus keeps "smooth" segments, but it's over-specific. NormalBasedSegmentation is clearer. I fix it today

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done !

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the rebase of the branch of this branch went so smoothly I doubted it had worked 👌

@DamienGilliard
Copy link
Collaborator Author

Et merci !!

@9and3
Copy link
Contributor

9and3 commented Jul 15, 2024

Hello @DamienGilliard ! As discussed here's the 🥔 ..
You can find an example file with internalized data I was testing here.

The metadata and wrap is there, just some work from c++ is needed.

As a note:

  • the cloud is passing as reference
  • with a threshold of app. 0.4 is giving the result from the image and only a very little number of clusters are associated

image

Let me know if you can make the associator a bit more tolerant to worse normal and less populated points as the one internalized the gh file.. thanks` 🦖

@DamienGilliard
Copy link
Collaborator Author

@9and3 I'm on it !

@DamienGilliard
Copy link
Collaborator Author

DamienGilliard commented Jul 16, 2024

Capture d'écran 2024-07-16 214321

[WIP]:

  • the point association has been changed and works better.
  • Some unnneeded deletions on the c++ side were causing trouble and have been removed

Next Step:

  • improve the refinement function that doesn't work as well as it should
  • find a way to remove unwanted points that are now associated as a result of the new point association technique:
    Capture d'écran 2024-07-16 220628

@9and3
Copy link
Contributor

9and3 commented Jul 17, 2024

  • find a way to remove unwanted points that are now associated as a result of the new point association technique:

this point can be achieved by euclidean clustering/filtering maybe

@9and3
Copy link
Contributor

9and3 commented Jul 19, 2024

Let me know when we can merge (I left a note for the DFMesh.hh header to be integrated with the isPointOnFace() method ;) )

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe here we could add the function to test if a point is on a mesh face @DamienGilliard ?

Copy link
Collaborator Author

@DamienGilliard DamienGilliard left a comment

Choose a reason for hiding this comment

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

your suggestion was implemented ;)

Comment on lines +98 to +136
bool DFMesh::IsPointOnFace(Eigen::Vector3d point, double associationThreshold)
{
/*
To check if the point is in the face, we take into account all the triangles forming the face.
We calculate the area of each triangle, then check if the sum of the areas of the tree triangles
formed by two of the points of the referencr triangle and our point is equal to the reference triangle area
(within a user-defined margin). If it is the case, the triangle is in the face.
*/
std::vector<Eigen::Vector3i> faceTriangles = this->Faces;
for (Eigen::Vector3i triangle : faceTriangles)
{
Eigen::Vector3d v0 = this->Vertices[triangle[0]];
Eigen::Vector3d v1 = this->Vertices[triangle[1]];
Eigen::Vector3d v2 = this->Vertices[triangle[2]];
Eigen::Vector3d n = (v1 - v0).cross(v2 - v0);
double normOfNormal = n.norm();
n.normalize();

Eigen::Vector3d projectedPoint = point - n * (n.dot(point - v0)) ;

double referenceTriangleArea = normOfNormal*0.5;
Eigen::Vector3d n1 = (v1 - v0).cross(projectedPoint - v0);
double area1 = n1.norm()*0.5;
Eigen::Vector3d n2 = (v2 - v1).cross(projectedPoint - v1);
double area2 = n2.norm()*0.5;
Eigen::Vector3d n3 = (v0 - v2).cross(projectedPoint - v2);
double area3 = n3.norm()*0.5;
double res = (area1 + area2 + area3 - referenceTriangleArea) / referenceTriangleArea;

// arbitrary value to avoid false positives (points that, when projected on the triangle, are in it, but that are actually located too far from the mesh to actually belong to it)
double maxProjectionDistance = std::min({(v1 - v0).norm(), (v2 - v1).norm(), (v0 - v2).norm()});

if (std::abs(res) < associationThreshold && (projectedPoint - point).norm() < maxProjectionDistance)
{
return true;
}
}
return false;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@9and3 It's there !

@9and3 9and3 marked this pull request as ready for review July 20, 2024 13:23
@9and3 9and3 merged commit be624c4 into main Jul 20, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants