Ocean
Loading...
Searching...
No Matches
JLinkage.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_GEOMETRY_JLINKAGE_H
9#define META_OCEAN_GEOMETRY_JLINKAGE_H
10
13
15#include "ocean/base/Subset.h"
16
17#include "ocean/math/Line2.h"
18#include "ocean/math/Matrix.h"
19
20#include <iterator>
21
22namespace Ocean
23{
24
25namespace Geometry
26{
27
28/**
29 * This class implements several J-linkage functions for pose/homography determination.
30 * J-linkage aims to fit multiple models from data given
31 * The J-linkage algorithm is an agglomerative clustering that proceeds by linking elements with Jaccard distance smaller than 1 and stop as soon as there are no such elements left.
32 * @ingroup geometry
33 */
34class OCEAN_GEOMETRY_EXPORT JLinkage
35{
36 protected:
37
38 /**
39 * Definition of a pair combining a point index with the distance to a reference.
40 */
41 typedef std::pair<Scalar, Index32> DistancePair;
42
43 public:
44
45 /**
46 * Calculates multiple homographies between two images transforming the projected planar object points between the two images using J-linkage
47 * The resulting homographies transform its image points defined in the left image to image points defined in the right image (rightPoint_i = H_i * leftPoint_i).<br>
48 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
49 * @param rightImagePoints Image points in the right camera
50 * @param correspondences Number of points correspondences
51 * @param width The width of the left image in pixel
52 * @param height The height of the left image in pixel
53 * @param homographies Resulting valid homographies for each image plane
54 * @param testCandidates Number of candidates used in for minimum sample set, with range [4, correspondences]
55 * @param leftPointForInitialModels Initial image points, one per each sample set
56 * @param squarePixelErrorAssignmentThreshold Maximal square pixel error of a valid projection of a 3D point onto the 2D image plane, with range (0, infinity)
57 * @param usedIndicesPerHomography Optional set of indices which will receive the indices of the used image correspondences per model, if defined
58 * @param refineHomographies Determines whether a not linear least square algorithm is used to increase the pose accuracies after J-linkage
59 * @param approximatedNeighborSearch Defines if speeded up spatial neighbor search is used
60 * @param randomGenerator Random number generator. If is not nullptr, RANSAC is used for homography determination within initial minimum sample set
61 * @return True, if successfully completed
62 */
63 static bool homographyMatrices(const ImagePoint* leftImagePoints, const ImagePoint* rightImagePoints, const size_t correspondences, const unsigned int width, const unsigned int height, SquareMatrices3& homographies, const unsigned int testCandidates, const ImagePoints& leftPointForInitialModels, const Scalar squarePixelErrorAssignmentThreshold, std::vector<IndexSet32>* usedIndicesPerHomography = nullptr, bool refineHomographies = true, bool approximatedNeighborSearch = true, Ocean::RandomGenerator* randomGenerator = nullptr);
64
65 /**
66 * Calculates multiple homographies between two images transforming the projected planar object points between the two images using J-linkage
67 * The resulting homographies transform its image points defined in the left image to image points defined in the right image (rightPoint_i = H_i * leftPoint_i).<br>
68 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
69 * @param rightImagePoints Image points in the right camera
70 * @param correspondences Number of points correspondences
71 * @param width The width of the left image in pixel
72 * @param height The height of the left image in pixel
73 * @param homographies Resulting valid homographies for each image plane
74 * @param testCandidates Number of candidates used in for minimum sample set, with range [4, correspondences]
75 * @param leftPointIndicesForInitialModels Initial indices of image points, one per each sample set
76 * @param squarePixelErrorAssignmentThreshold Maximal square pixel error of a valid projection of a 3D point onto the 2D image plane, with range (0, infinity)
77 * @param usedIndicesPerHomography Optional set of indices which will receive the indices of the used image correspondences per model, if defined
78 * @param refineHomographies Determines whether a not linear least square algorithm is used to increase the pose accuracies after J-linkage
79 * @param approximatedNeighborSearch Defines if speeded up spatial neighbor search is used
80 * @param randomGenerator Random number generator. If is not nullptr, RANSAC is used for homography determination within initial minimum sample set
81 * @return True, if successfully completed
82 */
83 static inline bool homographyMatrices(const ImagePoint* leftImagePoints, const ImagePoint* rightImagePoints, const size_t correspondences, const unsigned int width, const unsigned int height, SquareMatrices3& homographies, const unsigned int testCandidates, const Indices32& leftPointIndicesForInitialModels, const Scalar squarePixelErrorAssignmentThreshold, std::vector<IndexSet32>* usedIndicesPerHomography = nullptr, bool refineHomographies = true, bool approximatedNeighborSearch = true, Ocean::RandomGenerator* randomGenerator = nullptr);
84
85 /**
86 * Multiple line detector using J-linkage
87 * @param imagePoints image points
88 * @param pointCount Number of points
89 * @param width The width of the image in pixel
90 * @param height The height of the image in pixel
91 * @param lines Resulting valid line model
92 * @param testCandidates Number of candidates used in for minimum sample set, with range [2, correspondences]
93 * @param pointForInitialModels Initial image points, one per each sample set
94 * @param pixelErrorAssignmentThreshold Maximal pixel error of a point-line corresspodance (0, infinity)
95 * @param usedIndicesPerHomography Optional set of indices which will receive the indices of the used image correspondences per model, if defined
96 * @param approximatedNeighborSearch Defines if speeded up spatial neighbor search is used
97 * @return True, if successfully completed
98 */
99 static bool fitLines(const ImagePoint* imagePoints, const size_t pointCount, const unsigned int width, const unsigned int height, Lines2& lines, const unsigned int testCandidates, const ImagePoints& pointForInitialModels, const Scalar pixelErrorAssignmentThreshold, std::vector<IndexSet32>* usedIndicesPerHomography = nullptr, bool approximatedNeighborSearch = true);
100
101 protected:
102
103 /**
104 * Generates minimal sample set for J-/T-Linkage
105 * @param imagePoints Image points
106 * @param pointCount Number of points
107 * @param pointForInitialModels Initial points of minimal sample sets. Note: some maybe be discarded
108 * @param testCandidates Number of candidates used for each minimal sampling set, with range [1, correspondences]
109 * @param distributionImagePoints Spatial distribution for approximate search (if nullptr, brute force methode is used)
110 * @return List of minimal sample sets (represented by indices)
111 */
112 static std::vector<Indices32> buildingMinimalSampleSet(const ImagePoint* imagePoints, const size_t pointCount, const ImagePoints& pointForInitialModels, const unsigned int testCandidates, const SpatialDistribution::DistributionArray* distributionImagePoints = nullptr);
113
114 /**
115 * Generates a homography per minimal sample set (for J-/T-Linkage)
116 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
117 * @param rightImagePoints Image points in the right camera
118 * @param correspondences Number of points correspondences
119 * @param leftPointForInitialModels Initial points of minimal sample sets. Note: some maybe be discarded
120 * @param testCandidates Number of candidates used for each minimal sampling set, with range [4, correspondences]
121 * @param distributionImagePoints Spatial distribution for approximate search (if nullptr, brute force methode is used)
122 * @param randomRansac Random generator object to be used for creating random numbers, RANSAC is used if this is not null
123 * @return Resulting homographies for each minimal sample set (its count is possibly smaller then the given image points)
124 */
125 static SquareMatrices3 buildingMinimalSampleSetHomography(const ImagePoint* leftImagePoints, const ImagePoint* rightImagePoints, const size_t correspondences, const ImagePoints& leftPointForInitialModels, const unsigned int testCandidates, const SpatialDistribution::DistributionArray* distributionImagePoints = nullptr, RandomGenerator* randomRansac = nullptr);
126
127 /**
128 * Generates a line model per minimal sample set (for J-/T-Linkage)
129 * @param imagePoints Image points
130 * @param pointCount Number of points
131 * @param pointForInitialModels Initial points of minimal sample sets. Note: some maybe be discarded
132 * @param testCandidates Number of candidates used for each minimal sampling set, with range [2, correspondences]
133 * @param distributionImagePoints Spatial distribution for approximate search (if nullptr, brute force methode is used)
134 * @return Resulting line for each minimal sample set (its count is possibly smaller then the given image points)
135 */
136 static Lines2 buildingMinimalSampleSetLine(const ImagePoint* imagePoints, const size_t pointCount, const ImagePoints& pointForInitialModels, const unsigned int testCandidates, const SpatialDistribution::DistributionArray* distributionImagePoints = nullptr);
137
138 /**
139 * Calculates the jaccard distance
140 * d(A, B) = ( |union(A, B)| - |intersection(A, B)| ) / |union(A, B)|.
141 * @param setA first set of indices to compare
142 * @param setB second set of indices to compare
143 * @return Jaccard distance [0, 1]
144 */
145 static inline Scalar jaccardDistance(const IndexSet32& setA, const IndexSet32& setB);
146
147 /**
148 * Sorts pairs of indices and their corresponding distances in ascending order regarding the distance values.
149 * @param firstPair First pair of distance and index
150 * @param seccondPair Second pair of distance and index
151 * @return True, if the distance value of the first pair is smaller than distance value of the second pair
152 */
153 static inline bool distancePairSortAscending(const DistancePair& firstPair, const DistancePair& seccondPair);
154};
155
156/**
157 * This class implements L-linkage functions for pose/homography determination.
158 * T-linkage aims to fit multiple models from data given
159 * The T-linkage algorithm is an agglomerative clustering that proceeds by linking elements with tanimoto distance smaller than 1 and stop as soon as there are no such elements left.
160 * @ingroup geometry
161 */
162class OCEAN_GEOMETRY_EXPORT TLinkage : JLinkage
163{
164 public:
165
166 /**
167 * Calculates multiple homographies between two images transforming the projected planar object points between the two images using T-linkage
168 * The resulting homographies transform its image points defined in the left image to image points defined in the right image (rightPoint_i = H_i * leftPoint_i).<br>
169 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
170 * @param rightImagePoints Image points in the right camera
171 * @param correspondences Number of points correspondences
172 * @param homographies Resulting valid homographies for each image plane
173 * @param testCandidates Number of candidates used in for minimum sample set, with range [8, correspondences]
174 * @param leftPointForInitialModels Initial image points, one per each sample set
175 * @param pixelAssignmentRadius Maximal pixel radius of image points being considered [5, image width)
176 * @param usedIndicesPerHomography Optional set of indices which will receive the indices of the used image correspondences per model, if defined
177 * @param refineHomographies Determines whether a not linear least square algorithm is used to increase the pose accuracies after J-linkage
178 * @param randomGenerator Random number generator. If is not nullptr, RANSAC is used for homography refinement
179 * @return True, if successfully completed
180 */
181 static bool homographyMatrices(const ImagePoint* leftImagePoints, const ImagePoint* rightImagePoints, const size_t correspondences, SquareMatrices3& homographies, const unsigned int testCandidates, const ImagePoints& leftPointForInitialModels, const Scalar pixelAssignmentRadius, std::vector<IndexSet32>* usedIndicesPerHomography = nullptr, bool refineHomographies = true, Ocean::RandomGenerator* randomGenerator = nullptr);
182
183 /**
184 * Multiple line detector using T-linkage
185 * @param imagePoints image points
186 * @param pointCount Number of points
187 * @param lines Resulting valid line model
188 * @param testCandidates Number of candidates used in for minimum sample set, with range [2, correspondences]
189 * @param pointForInitialModels Initial image points, one per each sample set
190 * @param pixelErrorAssignmentThreshold Maximal pixel error of a point-line corresspodance (0, infinity)
191 * @param usedIndicesPerHomography Optional set of indices which will receive the indices of the used image correspondences per model, if defined
192 * @return True, if successfully completed
193 */
194 static bool fitLines(const ImagePoint* imagePoints, const size_t pointCount, Lines2& lines, const unsigned int testCandidates, const ImagePoints& pointForInitialModels, const Scalar pixelErrorAssignmentThreshold, std::vector<IndexSet32>* usedIndicesPerHomography = nullptr);
195
196 private:
197
198 /**
199 * Calculates the tanimoto distance
200 * d(A, B) = 1 - A*B / (A*A + B*B - A*B).<BR>
201 * A and B must have the same amount of elements
202 * @param vectorA first vector to compare
203 * @param vectorB second vector to compare
204 * @return Tanimoto distance [0, 1]
205 */
206 static inline Scalar tanimotoDistance(const Matrix& vectorA, const Matrix& vectorB);
207};
208
209inline bool JLinkage::homographyMatrices(const ImagePoint* leftImagePoints, const ImagePoint* rightImagePoints, const size_t correspondences, const unsigned int width, const unsigned int height, SquareMatrices3 & homographies, const unsigned int testCandidates, const Indices32& leftPointIndicesForInitialModels, const Scalar squarePixelErrorAssignmentThreshold, std::vector<IndexSet32>* usedIndicesPerHomography, bool refineHomographies, bool approximatedNeighborSearch, Ocean::RandomGenerator* randomGenerator)
210{
211 const ImagePoints leftPointForInitialModels(Subset::subset(leftImagePoints, correspondences, leftPointIndicesForInitialModels));
212
213 return homographyMatrices(leftImagePoints, rightImagePoints, correspondences, width, height, homographies, testCandidates, leftPointForInitialModels, squarePixelErrorAssignmentThreshold, usedIndicesPerHomography, refineHomographies, approximatedNeighborSearch, randomGenerator);
214}
215
217{
218 if (setA.empty() || setB.empty())
219 {
220 return 0;
221 }
222
223 Indices32 intersectionSet;
224 std::set_intersection(setA.cbegin(), setA.cend(), setB.cbegin(), setB.cend(), std::back_inserter(intersectionSet));
225
226 Indices32 unionSet;
227 std::set_union(setA.cbegin(), setA.cend(), setB.cbegin(), setB.cend(), std::back_inserter(unionSet));
228
229 const Scalar numberIntersections = Scalar(intersectionSet.size());
230 const Scalar numberUnion = Scalar(unionSet.size());
231
232 ocean_assert(unionSet.size() >= 1);
233 return (numberUnion - numberIntersections) / numberUnion;
234}
235
236inline bool JLinkage::distancePairSortAscending(const DistancePair& firstPair, const DistancePair& seccondPair)
237{
238 return firstPair.first < seccondPair.first;
239}
240
241inline Scalar TLinkage::tanimotoDistance(const Matrix& vectorA, const Matrix& vectorB)
242{
243 ocean_assert((vectorA.columns() == 1u || vectorA.rows() == 1u) && (vectorB.columns() == 1u || vectorB.rows() == 1u));
244 ocean_assert(vectorA.elements() == vectorB.elements());
245
246 size_t length = vectorA.elements();
247
248 Scalar squaredNormAB(0);
249 Scalar squaredNormA(0);
250 Scalar squaredNormB(0);
251
252 for (size_t n = 0u; n < length; ++n)
253 {
254 squaredNormA += Numeric::sqr(vectorA.data()[n]);
255 squaredNormB += Numeric::sqr(vectorB.data()[n]);
256 squaredNormAB += vectorA.data()[n] * vectorB.data()[n];
257 }
258
259 return (1 - Numeric::ratio(squaredNormAB, squaredNormA + squaredNormB - squaredNormAB));
260}
261
262}
263
264}
265
266#endif // META_OCEAN_GEOMETRY_JLINKAGE_H
This class implements several J-linkage functions for pose/homography determination.
Definition JLinkage.h:35
static Scalar jaccardDistance(const IndexSet32 &setA, const IndexSet32 &setB)
Calculates the jaccard distance d(A, B) = ( |union(A, B)| - |intersection(A, B)| ) / |union(A,...
Definition JLinkage.h:216
static bool distancePairSortAscending(const DistancePair &firstPair, const DistancePair &seccondPair)
Sorts pairs of indices and their corresponding distances in ascending order regarding the distance va...
Definition JLinkage.h:236
static bool fitLines(const ImagePoint *imagePoints, const size_t pointCount, const unsigned int width, const unsigned int height, Lines2 &lines, const unsigned int testCandidates, const ImagePoints &pointForInitialModels, const Scalar pixelErrorAssignmentThreshold, std::vector< IndexSet32 > *usedIndicesPerHomography=nullptr, bool approximatedNeighborSearch=true)
Multiple line detector using J-linkage.
static std::vector< Indices32 > buildingMinimalSampleSet(const ImagePoint *imagePoints, const size_t pointCount, const ImagePoints &pointForInitialModels, const unsigned int testCandidates, const SpatialDistribution::DistributionArray *distributionImagePoints=nullptr)
Generates minimal sample set for J-/T-Linkage.
static Lines2 buildingMinimalSampleSetLine(const ImagePoint *imagePoints, const size_t pointCount, const ImagePoints &pointForInitialModels, const unsigned int testCandidates, const SpatialDistribution::DistributionArray *distributionImagePoints=nullptr)
Generates a line model per minimal sample set (for J-/T-Linkage)
static bool homographyMatrices(const ImagePoint *leftImagePoints, const ImagePoint *rightImagePoints, const size_t correspondences, const unsigned int width, const unsigned int height, SquareMatrices3 &homographies, const unsigned int testCandidates, const ImagePoints &leftPointForInitialModels, const Scalar squarePixelErrorAssignmentThreshold, std::vector< IndexSet32 > *usedIndicesPerHomography=nullptr, bool refineHomographies=true, bool approximatedNeighborSearch=true, Ocean::RandomGenerator *randomGenerator=nullptr)
Calculates multiple homographies between two images transforming the projected planar object points b...
static SquareMatrices3 buildingMinimalSampleSetHomography(const ImagePoint *leftImagePoints, const ImagePoint *rightImagePoints, const size_t correspondences, const ImagePoints &leftPointForInitialModels, const unsigned int testCandidates, const SpatialDistribution::DistributionArray *distributionImagePoints=nullptr, RandomGenerator *randomRansac=nullptr)
Generates a homography per minimal sample set (for J-/T-Linkage)
std::pair< Scalar, Index32 > DistancePair
Definition of a pair combining a point index with the distance to a reference.
Definition JLinkage.h:41
This class implements a distribution array.
Definition SpatialDistribution.h:228
This class implements L-linkage functions for pose/homography determination.
Definition JLinkage.h:163
static bool homographyMatrices(const ImagePoint *leftImagePoints, const ImagePoint *rightImagePoints, const size_t correspondences, SquareMatrices3 &homographies, const unsigned int testCandidates, const ImagePoints &leftPointForInitialModels, const Scalar pixelAssignmentRadius, std::vector< IndexSet32 > *usedIndicesPerHomography=nullptr, bool refineHomographies=true, Ocean::RandomGenerator *randomGenerator=nullptr)
Calculates multiple homographies between two images transforming the projected planar object points b...
static bool fitLines(const ImagePoint *imagePoints, const size_t pointCount, Lines2 &lines, const unsigned int testCandidates, const ImagePoints &pointForInitialModels, const Scalar pixelErrorAssignmentThreshold, std::vector< IndexSet32 > *usedIndicesPerHomography=nullptr)
Multiple line detector using T-linkage.
static Scalar tanimotoDistance(const Matrix &vectorA, const Matrix &vectorB)
Calculates the tanimoto distance d(A, B) = 1 - A*B / (A*A + B*B - A*B).
Definition JLinkage.h:241
size_t columns() const
Returns the count of columns.
Definition Matrix.h:698
const T * data() const
Returns a pointer to the internal values.
Definition Matrix.h:798
size_t elements() const
Returns the number of entire elements, which is the product of rows and columns.
Definition Matrix.h:704
size_t rows() const
Returns the count of rows.
Definition Matrix.h:692
static constexpr T ratio(const T nominator, const T denominator, const T fallback=T(1))
Returns the ratio between two values if the denominator is not equal a small epsilon.
Definition Numeric.h:2076
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition Numeric.h:1495
This class implements a generator for random numbers.
Definition RandomGenerator.h:42
static std::vector< T > subset(const std::vector< T > &objects, const std::vector< TIndex > &indices)
Extracts a subset of a given set of objects by usage of an index vector holding the indices of all ob...
Definition Subset.h:751
std::set< Index32 > IndexSet32
Definition of a set holding 32 bit indices.
Definition Base.h:114
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition Base.h:96
std::vector< ImagePoint > ImagePoints
Definition of a vector holding 2D image points.
Definition geometry/Geometry.h:123
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Line2 > Lines2
Definition of a vector holding Line2 objects.
Definition Line2.h:57
std::vector< SquareMatrix3 > SquareMatrices3
Definition of a vector holding SquareMatrix3 objects.
Definition SquareMatrix3.h:71
The namespace covering the entire Ocean framework.
Definition Accessor.h:15