Ocean
Loading...
Searching...
No Matches
PoseProjection.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_TRACKING_POSE_PROJECTION_H
9#define META_OCEAN_TRACKING_POSE_PROJECTION_H
10
12
13#include "ocean/base/Worker.h"
14
16
18
21
24
25#include <algorithm>
26
27namespace Ocean
28{
29
30namespace Tracking
31{
32
33/**
34 * This class implements a pose projection.
35 * @ingroup tracking
36 */
37class OCEAN_TRACKING_EXPORT PoseProjection
38{
39 public:
40
41 /**
42 * Creates an empty pose projection object.
43 */
45
46 /**
47 * Creates a new pose projection object by a given pose and object points.
48 * @param pose Pose used to project the object points to the image plane
49 * @param pinholeCamera The pinhole camera object defining the projection
50 * @param objectPoints Object points to be projected
51 * @param number Number Of object points to be projected
52 * @param distortImagePoints Distorts the image points after projection if True
53 */
54 PoseProjection(const HomogenousMatrix4& pose, const PinholeCamera& pinholeCamera, const Geometry::ObjectPoint* objectPoints, const size_t number, const bool distortImagePoints);
55
56 /**
57 * Returns the pose of this projection.
58 * @return Projection pose
59 */
60 inline const HomogenousMatrix4& pose() const;
61
62 /**
63 * Returns the image points (the projected object points) of this pose projection.
64 * @return Pose image points
65 */
66 inline const Geometry::ImagePoints& imagePoints() const;
67
68 /**
69 * Returns the distortion state of this projection.
70 * @return Distortion state
71 */
72 inline CV::Detector::PointFeature::DistortionState distortionState() const;
73
74 /**
75 * Returns the number of stored pose points.
76 * @return Pose points
77 */
78 inline size_t size() const;
79
80 /**
81 * Returns the robust minimal average square error between this pose projection and a given 2D point cloud.
82 * The number of given image points must be equal or small to the number of internal pose points of this object.
83 * @param imagePoints Image points to find corresponding pose points for
84 * @param numberImagePoints Number of given image points
85 * @param validImagePoints Number of valid image points expecting to have corresponding points in the pose points, with range [1, numberImagePoints]
86 * @param errorDetermination Depending on this flag uniqueAveragedRobustErrorInPointCloud, approximatedAveragedRobustErrorInPointCloud() or ambiguousAveragedRobustErrorInPointCloud() will be used
87 * @return Resulting minimal average square error
88 * @tparam tEstimator Estimator to be applied
89 */
90 template <Geometry::Estimator::EstimatorType tEstimator>
91 Scalar minimalAverageSquareError(const Geometry::ImagePoint* imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination);
92
93 /**
94 * Returns whether this pose projection holds no points.
95 * @return True, if so
96 */
97 inline bool isEmpty() const;
98
99 /**
100 * Returns whether this pose projection holds at least one point.
101 * @return True, if so
102 */
103 explicit inline operator bool() const;
104
105 private:
106
107 /**
108 * Converts an element to an object point.
109 * @param element Element to be converted
110 * @return Converted object point
111 */
112 static inline const Vector3& objectPoint2objectPoint(const Geometry::ObjectPoint& element);
113
114 private:
115
116 /// Pose of this projection.
118
119 /// Projection object points for this pose.
121
122 /// Distortion state of the image points.
124};
125
126/**
127 * This class implements a set of pose projections.
128 * @ingroup tracking
129 */
130 class OCEAN_TRACKING_EXPORT PoseProjectionSet
131 {
132 public:
133
134 /**
135 * Definition of a vector holding pose projections.
136 */
137 typedef std::vector<PoseProjection> PoseProjections;
138
139 /**
140 * This class implements a error object.
141 */
143 {
144 public:
145
146 /**
147 * Creates a new error object.
148 * @param index Index of the element
149 * @param error Error of the element
150 */
151 inline ErrorObject(const unsigned int index, const Scalar error);
152
153 /**
154 * Returns the index of this object.
155 * @return Object index
156 */
157 inline unsigned int index() const;
158
159 /**
160 * Returns the error of this object.
161 * @return Object error
162 */
163 inline Scalar error() const;
164
165 /**
166 * Returns whether the left object has a lesser error value than the right one.
167 * @param object Right error object to compare
168 * @return True, if so
169 */
170 inline bool operator<(const ErrorObject& object) const;
171
172 private:
173
174 /// Object index.
175 unsigned int objectIndex;
176
177 /// Object error.
179 };
180
181 /**
182 * Definition of a vector holding error objects.
183 */
184 typedef std::vector<ErrorObject> ErrorObjects;
185
186 public:
187
188 /**
189 * Creates an empty set of pose projections.
190 */
192
193 /**
194 * Destructs a set of pose projections.
195 */
197
198 /**
199 * Returns the width of the camera in pixel used for all projections.
200 * @return The camera width in pixels
201 * @see height().
202 */
203 inline unsigned int width() const;
204
205 /**
206 * Returns the height of the camera in pixel used for all projections.
207 * @return The camera height in pixels
208 * @see width().
209 */
210 inline unsigned int height() const;
211
212 /**
213 * Adds a new pose projection.
214 * @param poseProjection Pose projection to be added
215 */
216 inline void addPoseProjection(const PoseProjection& poseProjection);
217
218 /**
219 * Returns the registered pose projections.
220 * @return Pose projections
221 */
222 inline const PoseProjections& poseProjections() const;
223
224 /**
225 * Returns the number of registered pose projections.
226 * @return Pose projection number
227 */
228 inline size_t size() const;
229
230 /**
231 * Sets the dimension of the camera used for all pose projections.
232 * @param width The camera width in pixel
233 * @param height The camera height in pixel
234 * @see width(), height().
235 */
236 inline void setDimension(const unsigned int width, const unsigned int height);
237
238 /**
239 * Clears the projection set.
240 */
241 void clear();
242
243 /**
244 * Returns the pose with the minimal distance error.
245 * The number of given image points must be equal or small to the number of internal pose points of this object.
246 * @param imagePoints Image points to find corresponding pose points for
247 * @param numberImagePoints Number of given image points
248 * @param validImagePoints Number of valid image points expecting to have corresponding points in the pose points, with range [1, numberImagePoints]
249 * @param errorDetermination Depending on this flag uniqueAveragedRobustErrorInPointCloud, approximatedAveragedRobustErrorInPointCloud() or ambiguousAveragedRobustErrorInPointCloud() will be used
250 * @param resultingError Optional resulting minimal average square error
251 * @param worker Optional worker object to distribute the computation
252 * @return Pose with minimal error
253 * @tparam tEstimator Estimator to be applied
254 */
255 template <Geometry::Estimator::EstimatorType tEstimator>
256 inline HomogenousMatrix4 findPoseWithMinimalError(const Geometry::ImagePoint* imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, Scalar* resultingError = nullptr, Worker* worker = nullptr);
257
258 /**
259 * Returns the poses with the minimal distance error.
260 * The number of given image points must be equal or small to the number of internal pose points of this object.
261 * @param imagePoints Image points to find corresponding pose points for
262 * @param numberImagePoints Number of given image points
263 * @param validImagePoints Number of valid image points expecting to have corresponding points in the pose points, with range [1, numberImagePoints]
264 * @param errorDetermination Depending on this flag uniqueAveragedRobustErrorInPointCloud, approximatedAveragedRobustErrorInPointCloud() or ambiguousAveragedRobustErrorInPointCloud() will be used
265 * @param numberPoses Number of poses to be found
266 * @param poses Resulting poses, make sure that the memory block provides enough space
267 * @param resultingErrors Optional resulting minimal average square errors individual for each returned pose, make sure that the memory block provides enough space
268 * @param worker Optional worker object to distribute the computation
269 * @return Number of found best poses
270 * @tparam tEstimator Estimator to be applied
271 */
272 template <Geometry::Estimator::EstimatorType tEstimator>
273 unsigned int findPosesWithMinimalError(const Geometry::ImagePoint* imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, const size_t numberPoses, HomogenousMatrix4* poses, Scalar* resultingErrors = nullptr, Worker* worker = nullptr);
274
275 /**
276 * Returns whether this set holds no pose projections.
277 * @return True, if so
278 */
279 inline bool isEmpty() const;
280
281 /**
282 * Returns whether this set holds at least one pose projection.
283 * @return True, if so
284 */
285 explicit inline operator bool() const;
286
287 private:
288
289 /**
290 * Returns the pose with the minimal distance error for a subset of the pose projections.
291 * @param imagePoints Image points to find corresponding pose points for
292 * @param numberImagePoints Number of given image points
293 * @param validImagePoints Number of valid image points expecting to have corresponding points in the pose points, with range [1, numberImagePoints]
294 * @param errorDetermination Depending on this flag uniqueAveragedRobustErrorInPointCloud, approximatedAveragedRobustErrorInPointCloud() or ambiguousAveragedRobustErrorInPointCloud() will be used
295 * @param errorObjects Error objects receiving the estimated error values
296 * @param firstProjection First projection to be handled
297 * @param numberProjections Number of projections to be handled
298 * @tparam tEstimator Estimator to be applied
299 */
300 template <Geometry::Estimator::EstimatorType tEstimator>
301 void findPoseWithMinimalErrorSubset(const Geometry::ImagePoint* imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, ErrorObject* errorObjects, const unsigned int firstProjection, const unsigned int numberProjections);
302
303 private:
304
305 /// All registered pose projections.
307
308 /// Width of the camera in pixel used for all pose projections
310
311 /// Height of the camera in pixel used for all pose projections
313};
314
316{
317 return objectPoint;
318}
319
321{
322 return poseTransformation;
323}
324
326{
327 return poseImagePoints;
328}
329
334
335inline size_t PoseProjection::size() const
336{
337 return poseImagePoints.size();
338}
339
340inline bool PoseProjection::isEmpty() const
341{
342 return poseImagePoints.empty();
343}
344
345inline PoseProjection::operator bool() const
346{
347 return !poseImagePoints.empty();
348}
349
350inline unsigned int PoseProjectionSet::width() const
351{
353}
354
355inline unsigned int PoseProjectionSet::height() const
356{
358}
359
360inline void PoseProjectionSet::setDimension(const unsigned int width, const unsigned int height)
361{
364}
365
366inline void PoseProjectionSet::addPoseProjection(const PoseProjection& poseProjection)
367{
368 projectionSetPoseProjections.push_back(poseProjection);
369}
370
375
376inline size_t PoseProjectionSet::size() const
377{
378 return projectionSetPoseProjections.size();
379}
380
381inline bool PoseProjectionSet::isEmpty() const
382{
383 return projectionSetPoseProjections.empty();
384}
385
386inline PoseProjectionSet::operator bool() const
387{
388 return !projectionSetPoseProjections.empty();
389}
390
391inline PoseProjectionSet::ErrorObject::ErrorObject(const unsigned int index, const Scalar error) :
392 objectIndex(index),
393 objectError(error)
394{
395 // nothing to do here
396}
397
398inline unsigned int PoseProjectionSet::ErrorObject::index() const
399{
400 return objectIndex;
401}
402
404{
405 return objectError;
406}
407
409{
410 return objectError < element.objectError;
411}
412
413template <Geometry::Estimator::EstimatorType tEstimator>
414Scalar PoseProjection::minimalAverageSquareError(const Geometry::ImagePoint* imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination)
415{
416 if (isEmpty())
417 return Numeric::maxValue();
418
419 const size_t points = min(size(), numberImagePoints);
420 const size_t validPoints = min(validImagePoints, points);
421
422 return Geometry::Error::averagedRobustErrorInPointCloud<tEstimator>(imagePoints, points, validPoints, poseImagePoints.data(), size(), errorDetermination);
423}
424
425template <Geometry::Estimator::EstimatorType tEstimator>
426HomogenousMatrix4 PoseProjectionSet::findPoseWithMinimalError(const Geometry::ImagePoint* imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, Scalar* resultingError, Worker* worker)
427{
428 ocean_assert(!isEmpty());
429
430 if (isEmpty())
431 return HomogenousMatrix4();
432
433 ErrorObjects errorObjects(projectionSetPoseProjections.size(), ErrorObject(0xFFFFFFFF, Numeric::maxValue()));
434
435 if (worker)
436 worker->executeFunction(Worker::Function::create(*this, &PoseProjectionSet::findPoseWithMinimalErrorSubset<tEstimator>, imagePoints, numberImagePoints, validImagePoints, errorDetermination, errorObjects.data(), 0u, 0u), 0u, size(), 5u, 6u);
437 else
438 findPoseWithMinimalErrorSubset<tEstimator>(imagePoints, numberImagePoints, validImagePoints, errorDetermination, errorObjects.data(), 0u, (unsigned int)size());
439
440 std::sort(errorObjects.begin(), errorObjects.end());
441
442 if (resultingError)
443 *resultingError = errorObjects.front().error();
444
445 ocean_assert(errorObjects.front().index() < projectionSetPoseProjections.size());
446 return projectionSetPoseProjections[errorObjects.front().index()].pose();
447}
448
449template <Geometry::Estimator::EstimatorType tEstimator>
450unsigned int PoseProjectionSet::findPosesWithMinimalError(const Geometry::ImagePoint* imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, const size_t numberPoses, HomogenousMatrix4* poses, Scalar* resultingErrors, Worker* worker)
451{
452 ocean_assert(poses);
453
454 if (isEmpty() || numberPoses == 0)
455 return 0;
456
457 ErrorObjects errorObjects(projectionSetPoseProjections.size(), ErrorObject(0xFFFFFFFF, Numeric::maxValue()));
458
459 if (worker)
460 worker->executeFunction(Worker::Function::create(*this, &PoseProjectionSet::findPoseWithMinimalErrorSubset<tEstimator>, imagePoints, numberImagePoints, validImagePoints, errorDetermination, errorObjects.data(), 0u, 0u), 0u, (unsigned int)size(), 5u, 6u);
461 else
462 findPoseWithMinimalErrorSubset<tEstimator>(imagePoints, numberImagePoints, validImagePoints, errorDetermination, errorObjects.data(), 0u, (unsigned int)size());
463
464 // **NOTE** We should seek a slightly larger set of best matching poses as we should try to find good poses but also different poses
465 // **NOTE** We should think about the application of more suitable data structures like KD-Trees to improve the performance
466
467 std::sort(errorObjects.begin(), errorObjects.end());
468
469 const size_t results = min(numberPoses, errorObjects.size());
470
471 for (size_t n = 0; n < results; ++n)
472 {
473 poses[n] = projectionSetPoseProjections[errorObjects[n].index()].pose();
474 if (resultingErrors)
475 resultingErrors[n] = errorObjects[n].error();
476 }
477
478 return (unsigned int)results;
479}
480
481template <Geometry::Estimator::EstimatorType tEstimator>
482void PoseProjectionSet::findPoseWithMinimalErrorSubset(const Geometry::ImagePoint* imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, ErrorObject* errorObjects, const unsigned int firstProjection, const unsigned int numberProjections)
483{
484 ocean_assert(imagePoints);
485 ocean_assert(errorObjects);
486
487 ocean_assert(firstProjection + numberProjections <= projectionSetPoseProjections.size());
488
489 for (unsigned int n = firstProjection; n < firstProjection + numberProjections; ++n)
490 {
491 const Scalar errorValue = projectionSetPoseProjections[n].minimalAverageSquareError<tEstimator>(imagePoints, numberImagePoints, validImagePoints, errorDetermination);
492 errorObjects[n] = ErrorObject(n, errorValue);
493 }
494}
495
496}
497
498}
499
500#endif // META_OCEAN_TRACKING_POSE_PROJECTION_H
DistortionState
Definition of individual distortion states.
Definition PointFeature.h:51
static Caller< void > create(CT &object, typename MemberFunctionPointerMaker< CT, void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a member function with no function parameter.
Definition Caller.h:3023
ErrorDetermination
Definition of different error determination stages.
Definition Error.h:41
static constexpr T maxValue()
Returns the max scalar value.
Definition Numeric.h:3244
This class implements a pose projection.
Definition PoseProjection.h:38
PoseProjection(const HomogenousMatrix4 &pose, const PinholeCamera &pinholeCamera, const Geometry::ObjectPoint *objectPoints, const size_t number, const bool distortImagePoints)
Creates a new pose projection object by a given pose and object points.
Scalar minimalAverageSquareError(const Geometry::ImagePoint *imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination)
Returns the robust minimal average square error between this pose projection and a given 2D point clo...
Definition PoseProjection.h:414
const Geometry::ImagePoints & imagePoints() const
Returns the image points (the projected object points) of this pose projection.
Definition PoseProjection.h:325
PoseProjection()
Creates an empty pose projection object.
const HomogenousMatrix4 & pose() const
Returns the pose of this projection.
Definition PoseProjection.h:320
HomogenousMatrix4 poseTransformation
Pose of this projection.
Definition PoseProjection.h:117
CV::Detector::PointFeature::DistortionState poseDistortionState
Distortion state of the image points.
Definition PoseProjection.h:123
size_t size() const
Returns the number of stored pose points.
Definition PoseProjection.h:335
CV::Detector::PointFeature::DistortionState distortionState() const
Returns the distortion state of this projection.
Definition PoseProjection.h:330
Geometry::ImagePoints poseImagePoints
Projection object points for this pose.
Definition PoseProjection.h:120
bool isEmpty() const
Returns whether this pose projection holds no points.
Definition PoseProjection.h:340
static const Vector3 & objectPoint2objectPoint(const Geometry::ObjectPoint &element)
Converts an element to an object point.
Definition PoseProjection.h:315
This class implements a error object.
Definition PoseProjection.h:143
bool operator<(const ErrorObject &object) const
Returns whether the left object has a lesser error value than the right one.
Definition PoseProjection.h:408
unsigned int objectIndex
Object index.
Definition PoseProjection.h:175
Scalar error() const
Returns the error of this object.
Definition PoseProjection.h:403
Scalar objectError
Object error.
Definition PoseProjection.h:178
ErrorObject(const unsigned int index, const Scalar error)
Creates a new error object.
Definition PoseProjection.h:391
unsigned int index() const
Returns the index of this object.
Definition PoseProjection.h:398
This class implements a set of pose projections.
Definition PoseProjection.h:131
unsigned int projectionSetCameraHeight
Height of the camera in pixel used for all pose projections.
Definition PoseProjection.h:312
HomogenousMatrix4 findPoseWithMinimalError(const Geometry::ImagePoint *imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, Scalar *resultingError=nullptr, Worker *worker=nullptr)
Returns the pose with the minimal distance error.
Definition PoseProjection.h:426
const PoseProjections & poseProjections() const
Returns the registered pose projections.
Definition PoseProjection.h:371
~PoseProjectionSet()
Destructs a set of pose projections.
PoseProjectionSet()
Creates an empty set of pose projections.
unsigned int findPosesWithMinimalError(const Geometry::ImagePoint *imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, const size_t numberPoses, HomogenousMatrix4 *poses, Scalar *resultingErrors=nullptr, Worker *worker=nullptr)
Returns the poses with the minimal distance error.
Definition PoseProjection.h:450
bool isEmpty() const
Returns whether this set holds no pose projections.
Definition PoseProjection.h:381
void setDimension(const unsigned int width, const unsigned int height)
Sets the dimension of the camera used for all pose projections.
Definition PoseProjection.h:360
void findPoseWithMinimalErrorSubset(const Geometry::ImagePoint *imagePoints, const size_t numberImagePoints, const size_t validImagePoints, const Geometry::Error::ErrorDetermination errorDetermination, ErrorObject *errorObjects, const unsigned int firstProjection, const unsigned int numberProjections)
Returns the pose with the minimal distance error for a subset of the pose projections.
Definition PoseProjection.h:482
std::vector< ErrorObject > ErrorObjects
Definition of a vector holding error objects.
Definition PoseProjection.h:184
void clear()
Clears the projection set.
unsigned int projectionSetCameraWidth
Width of the camera in pixel used for all pose projections.
Definition PoseProjection.h:309
PoseProjections projectionSetPoseProjections
All registered pose projections.
Definition PoseProjection.h:306
void addPoseProjection(const PoseProjection &poseProjection)
Adds a new pose projection.
Definition PoseProjection.h:366
unsigned int width() const
Returns the width of the camera in pixel used for all projections.
Definition PoseProjection.h:350
std::vector< PoseProjection > PoseProjections
Definition of a vector holding pose projections.
Definition PoseProjection.h:137
size_t size() const
Returns the number of registered pose projections.
Definition PoseProjection.h:376
unsigned int height() const
Returns the height of the camera in pixel used for all projections.
Definition PoseProjection.h:355
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
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
HomogenousMatrixT4< Scalar > HomogenousMatrix4
Definition of the HomogenousMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag eit...
Definition HomogenousMatrix4.h:44
The namespace covering the entire Ocean framework.
Definition Accessor.h:15