Skip to content

Commit bf1ccc6

Browse files
WIP-ADD: FastGlobalRegistrationBasedOnFeatureCorrespondence method added to registration class
1 parent f35e0df commit bf1ccc6

File tree

3 files changed

+59
-9
lines changed

3 files changed

+59
-9
lines changed

src/diffCheck/registration/registration.cc

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,24 @@
22

33
namespace diffCheck::registration
44
{
5-
open3d::pipelines::registration::RegistrationResult Registration::O3DFastGlobalRegistrationFeatureMatching(std::shared_ptr<geometry::DFPointCloud> source, std::shared_ptr<geometry::DFPointCloud> target)
5+
/*
6+
Documentation on Fast Point Feature Historigrams: https://pcl.readthedocs.io/projects/tutorials/en/latest/fpfh_estimation.html
7+
8+
Very simply, point features are values computed on a point cloud (for example the normal of a point, the curvature, etc.).
9+
point features historigrams generalize this concept by computing point features in a local neighborhood of a point, stored as higher-dimentional historigrams.
10+
11+
For example, for a given point, you take all the neighboring points within a given radius, and create a complete graph on those vertices.
12+
then for each edge of the graph you compute features that are then stored in a historigram of the original center point from which the sphere and the graph where built.
13+
https://pcl.readthedocs.io/projects/tutorials/en/latest/pfh_estimation.html#pfh-estimation proposes a simple example of such a historigram.
14+
15+
PCL's documentation refers to this 2009 TUM PhD thesis (but largely outside the scope of our work): https://mediatum.ub.tum.de/doc/800632/941254.pdf
16+
17+
Quite important for us: the resultant hyperspace is dependent on the quality of the surface normal estimations at each point (if pc noisy, historigram different).
18+
*/
19+
open3d::pipelines::registration::RegistrationResult Registration::O3DFastGlobalRegistrationFeatureMatching(std::shared_ptr<geometry::DFPointCloud> source, std::shared_ptr<geometry::DFPointCloud> target)
620
{
7-
auto sourceO3D = source->Cvt2O3DPointCloud();
8-
auto targetO3D = target->Cvt2O3DPointCloud();
21+
std::shared_ptr<open3d::geometry::PointCloud> sourceO3D = source->Cvt2O3DPointCloud();
22+
std::shared_ptr<open3d::geometry::PointCloud> targetO3D = target->Cvt2O3DPointCloud();
923

1024
sourceO3D->RandomDownSample(0.1);
1125
targetO3D->RandomDownSample(0.1);
@@ -27,4 +41,37 @@ namespace diffCheck::registration
2741

2842
return result;
2943
}
30-
} // namespace diffCheck::registration
44+
/*
45+
Very little information on this registration method compared to the previous one.
46+
If I understand correctly, this method finds keypoints in the FPFH hyperspaces of the source and target point clouds and then tries to match them.
47+
https://pcl.readthedocs.io/projects/tutorials/en/latest/correspondence_grouping.html
48+
*/
49+
open3d::pipelines::registration::RegistrationResult Registration::O3DFastGlobalRegistrationBasedOnCorrespondence(std::shared_ptr<geometry::DFPointCloud> source, std::shared_ptr<geometry::DFPointCloud> target)
50+
{
51+
std::shared_ptr<open3d::geometry::PointCloud> sourceO3D = source->Cvt2O3DPointCloud();
52+
std::shared_ptr<open3d::geometry::PointCloud> targetO3D = target->Cvt2O3DPointCloud();
53+
54+
sourceO3D->RandomDownSample(0.1);
55+
targetO3D->RandomDownSample(0.1);
56+
57+
std::shared_ptr<open3d::pipelines::registration::FastGlobalRegistrationOption> option = std::make_shared<open3d::pipelines::registration::FastGlobalRegistrationOption>();
58+
option->maximum_correspondence_distance_ = 0.05;
59+
option->iteration_number_ = 100;
60+
option->maximum_tuple_count_ = 500;
61+
62+
std::shared_ptr<open3d::pipelines::registration::Feature> sourceFPFHFeatures = open3d::pipelines::registration::ComputeFPFHFeature(*sourceO3D,
63+
open3d::geometry::KDTreeSearchParamHybrid(0.25, 30));
64+
std::shared_ptr<open3d::pipelines::registration::Feature> targetFPFHFeatures = open3d::pipelines::registration::ComputeFPFHFeature(*targetO3D,
65+
open3d::geometry::KDTreeSearchParamHybrid(0.25, 30));
66+
67+
68+
open3d::pipelines::registration::CorrespondenceSet correspondanceset;
69+
correspondanceset = open3d::pipelines::registration::CorrespondencesFromFeatures(*sourceFPFHFeatures, *targetFPFHFeatures);
70+
71+
auto result = open3d::pipelines::registration::FastGlobalRegistrationBasedOnCorrespondence(*sourceO3D,
72+
*targetO3D,
73+
correspondanceset,
74+
*option);
75+
return result;
76+
}
77+
}

src/diffCheck/registration/registration.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ class Registration
1010
public:
1111

1212
open3d::pipelines::registration::RegistrationResult O3DFastGlobalRegistrationFeatureMatching(std::shared_ptr<geometry::DFPointCloud> source, std::shared_ptr<geometry::DFPointCloud> target);
13+
14+
open3d::pipelines::registration::RegistrationResult O3DFastGlobalRegistrationBasedOnCorrespondence(std::shared_ptr<geometry::DFPointCloud> source, std::shared_ptr<geometry::DFPointCloud> target);
1315
};
1416
}

src/diffCheckApp.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,25 @@ int main()
1616
std::shared_ptr<diffCheck::geometry::DFPointCloud> dfPointCloudPtrAfterReg = std::make_shared<diffCheck::geometry::DFPointCloud>();
1717
std::shared_ptr<diffCheck::geometry::DFMesh> dfMeshPtr = std::make_shared<diffCheck::geometry::DFMesh>();
1818

19-
std::string pathCloud = R"(C:\Users\localuser\Downloads\00_pt.ply)";
20-
std::string pathMesh = R"(C:\Users\localuser\Downloads\00_mesh.ply)";
19+
std::string pathCloud = R"(C:\Users\localuser\Downloads\04_pt.ply)";
20+
std::string pathMesh = R"(C:\Users\localuser\Downloads\04_mesh.ply)";
2121
// std::string pathMesh = R"(F:\diffCheck\temp\03_mesh.ply)";
2222

2323
dfMeshPtr->LoadFromPLY(pathMesh);
2424
dfPointCloudPtr->LoadFromPLY(pathCloud);
2525

2626
// create a rigid rotation matrix
2727
Eigen::Matrix4d T = Eigen::Matrix4d::Identity();
28-
T.block<3, 3>(0, 0) = Eigen::AngleAxisd(3 , Eigen::Vector3d::UnitZ()).toRotationMatrix(); // Yes, Pi = 3 in this case
29-
T(0, 3) = 1;
30-
T(1, 3) = 4;
28+
T.block<3, 3>(0, 0) = Eigen::AngleAxisd(3 , Eigen::Vector3d::UnitZ()).toRotationMatrix(); // Yes, Pi = 3 in this world
29+
T(0, 3) = 10;
30+
T(1, 3) = -40;
3131

3232
std::shared_ptr<open3d::geometry::PointCloud> o3DPointCloudAfterTrans = std::make_shared<open3d::geometry::PointCloud>(dfPointCloudPtr->Cvt2O3DPointCloud()->Transform(T));
3333
dfPointCloudPtrAfterTrans->Cvt2DFPointCloud(o3DPointCloudAfterTrans);
3434

3535
std::shared_ptr<diffCheck::registration::Registration> reg = std::make_shared<diffCheck::registration::Registration>();
3636
auto result = reg->O3DFastGlobalRegistrationFeatureMatching(dfPointCloudPtrAfterTrans, dfPointCloudPtr);
37+
//auto result = reg->O3DFastGlobalRegistrationBasedOnCorrespondence(dfPointCloudPtrAfterTrans, dfPointCloudPtr);
3738

3839
// apply the transformation to the source point cloud
3940
Eigen::Matrix<double, 4, 4> transformation = result.transformation_;

0 commit comments

Comments
 (0)