Ocean
Loading...
Searching...
No Matches
RANSAC.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_RANSAC_H
9#define META_OCEAN_GEOMETRY_RANSAC_H
10
17
18#include "ocean/base/Accessor.h"
19#include "ocean/base/Lock.h"
21#include "ocean/base/Subset.h"
22#include "ocean/base/Worker.h"
23
24#include "ocean/math/Box3.h"
26#include "ocean/math/Numeric.h"
29
30namespace Ocean
31{
32
33namespace Geometry
34{
35
36/**
37 * This class implements several RANSAC functions for pose determination.
38 * @ingroup geometry
39 */
40class OCEAN_GEOMETRY_EXPORT RANSAC
41{
42 protected:
43
44 /**
45 * Definition of a function pointer determining a geometric transformation e.g., a affine transformation.
46 * Parameter0: Pointer to the left image point, must be valid
47 * Parameter1: Pointer to the right image points, must be valid
48 * Parameter2: Number of point correspondences, with range [1, infinity)
49 * Parameter3: Resulting transformation
50 * Return parameter: True, if succeeded
51 */
52 using GeometricTransformFunction = bool(*)(const Vector2*, const Vector2*, const size_t, SquareMatrix3&);
53
54 public:
55
56 /**
57 * Calculates the number of iterations necessary to find an outlier-free model data set.
58 * @param model Number of data elements sufficient to define a test model
59 * @param successProbability Probability that at least one outlier-free model will be selected, with range (0, 1)
60 * @param faultyRate Rate of faulty data elements inside the given data set, with range [0, 1)
61 * @param maximalIterations The number of maximal iterations which can be returned, with range [1, infinity)
62 * @return Minimal number of iterations to guarantee the specified probability, with range [1, maximalIterations]
63 */
64 static unsigned int iterations(const unsigned int model, const Scalar successProbability = Scalar(0.99), const Scalar faultyRate = Scalar(0.2), const unsigned int maximalIterations = 1000000u);
65
66 /**
67 * Calculates a pose using the perspective pose problem with three point correspondences using any camera.
68 * The specified point correspondences should be sorted by strength or stability to enhance the pose determination.<br>
69 * @param anyCamera The camera object specifying the projection, must be valid
70 * @param objectPointAccessor The accessor providing the 3D object points, at least 4
71 * @param imagePointAccessor The accessor providing the 2D image points, one image point for each object point
72 * @param randomGenerator A random generator to be used
73 * @param world_T_camera The resulting pose transforming camera points to world points
74 * @param minimalValidCorrespondences Minimal number of valid correspondences, with range [4, objectPointAccessor.size()]
75 * @param refine Determines whether a not linear least square algorithm is used to increase the pose accuracy after the RANSAC step
76 * @param iterations Number of maximal RANSAC iterations, with range [1, infinity)
77 * @param sqrPixelErrorThreshold Square pixel error threshold for valid RANSAC candidates, with range (0, infinity)
78 * @param usedIndices Optional vector receiving the indices of all valid correspondences
79 * @param sqrAccuracy Optional resulting average square pixel error
80 * @param gravityConstraints Optional gravity constraints to guide the pose estimation, nullptr otherwise
81 * @return True, if succeeded
82 */
83 static bool p3p(const AnyCamera& anyCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, HomogenousMatrix4& world_T_camera, const unsigned int minimalValidCorrespondences = 5u, const bool refine = true, const unsigned int iterations = 20u, const Scalar sqrPixelErrorThreshold = Scalar(5 * 5), Indices32* usedIndices = nullptr, Scalar* sqrAccuracy = nullptr, const GravityConstraints* gravityConstraints = nullptr);
84
85 /**
86 * Deprecated.
87 *
88 * Calculates a pose using the perspective pose problem with three point correspondences.
89 * The specified point correspondences should be sorted by strength or stability to enhance the pose determination.<br>
90 * This function does not used any apriori information (like e.g. a previous pose).<br>
91 * Beware: There is another p3p() function with almost identical functionality/parameter layout.<br>
92 * However, this function here supports 'weights' parameters and thus creates a bigger binary footprint.
93 * @param pinholeCamera The pinhole camera object specifying the intrinsic camera parameters
94 * @param objectPointAccessor The accessor providing the 3D object points, at least 4
95 * @param imagePointAccessor The accessor providing the 2D image points, one image point for each object point
96 * @param randomGenerator A random generator object
97 * @param useDistortionParameters True, if the provided image points are distorted and if the camera's distortion parameters should be applied during the pose determination
98 * @param pose Resulting pose
99 * @param minimalValidCorrespondences Minimal number of valid correspondences
100 * @param refine Determines whether a not linear least square algorithm is used to increase the pose accuracy after the RANSAC step
101 * @param iterations Number of maximal RANSAC iterations, with range [1, infinity)
102 * @param sqrPixelErrorThreshold Square pixel error threshold for valid RANSAC candidates, with range (0, infinity)
103 * @param usedIndices Optional vector receiving the indices of all valid correspondences
104 * @param sqrAccuracy Optional resulting average square pixel error
105 * @param weights Optional explicit weights to weight the point correspondences individually
106 * @return True, if succeeded
107 */
108 static inline bool p3p(const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, const unsigned int minimalValidCorrespondences, const bool refine, const unsigned int iterations, const Scalar sqrPixelErrorThreshold, Indices32* usedIndices, Scalar* sqrAccuracy, const Scalar* weights);
109
110 /**
111 * Calculates a camera pose using the perspective pose problem with three point correspondences.
112 * The calculation uses a rough camera pose (e.g., from a previous camera frame) to increase the robustness.
113 * @param world_T_roughCamera The already known rough camera pose, transforming rough camera points to world points, with default camera pointing towards the negative z-space with y-axis upwards, must be valid
114 * @param camera The camera profile defining the project, must be valid
115 * @param objectPointAccessor The accessor providing the 3D object points, at least 4
116 * @param imagePointAccessor The accessor providing the 2D image points, one image point for each 3D object point
117 * @param randomGenerator The random generator to be used
118 * @param world_T_camera The resulting camera pose, transforming camera points to world points, with default camera pointing towards the negative z-space with y-axis upwards, must be valid
119 * @param maxPositionOffset Maximal position offset between initial and final pose for three axis
120 * @param maxOrientationOffset Maximal orientation offset between initial and final pose in radian angle
121 * @param minValidCorrespondences Minimal number of valid correspondences
122 * @param refine True, if optimization step will be applied to increase the pose accuracy after the RANSAC step
123 * @param iterations Number of maximal RANSAC iterations, with range [1, infinity)
124 * @param sqrPixelErrorThreshold Square pixel error threshold for valid RANSAC candidates, with range (0, infinity)
125 * @param usedIndices Optional vector receiving the indices of all valid correspondences
126 * @param sqrAccuracy Optional resulting average square pixel error, with range [0, infinity)
127 * @param weights Optional weights to weight the individual point correspondences individually, nullptr to use the same weight for all point correspondences
128 * @return True, if succeeded
129 */
130 static inline bool p3p(const HomogenousMatrix4& world_T_roughCamera, const AnyCamera& camera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, HomogenousMatrix4& world_T_camera, const Vector3& maxPositionOffset = Vector3(Scalar(0.1), Scalar(0.1), Scalar(0.1)), const Scalar maxOrientationOffset = Numeric::deg2rad(10), const unsigned int minValidCorrespondences = 5u, const bool refine = true, const unsigned int iterations = 20u, const Scalar sqrPixelErrorThreshold = Scalar(5 * 5), Indices32* usedIndices = nullptr, Scalar* sqrAccuracy = nullptr, const Scalar* weights = nullptr);
131
132 /**
133 * Deprecated.
134 *
135 * Calculates a pose using the perspective pose problem with three point correspondences.
136 * The calculation uses a pose from a previous calculation to increase the robustness.<br>
137 * The specified point correspondences should be sorted by strength or stability to enhance the pose determination.<br>
138 * This function uses a rough pose as apriori information to improve the robustness of the result.
139 * @param initialPose Rough initial pose to increase determination robustness
140 * @param pinholeCamera The pinhole camera object specifying the intrinsic camera parameters
141 * @param objectPointAccessor The accessor providing the 3D object points, at least 4
142 * @param imagePointAccessor The accessor providing the 2D image points, one image point for each object point
143 * @param randomGenerator A random generator object
144 * @param useDistortionParameters True, if the provided image points are distorted and if the camera's distortion parameters should be applied during the pose determination
145 * @param pose Resulting pose
146 * @param maxPositionOffset Maximal position offset between initial and final pose for three axis
147 * @param maxOrientationOffset Maximal orientation offset between initial and final pose in radian angle
148 * @param minValidCorrespondences Minimal number of valid correspondences
149 * @param refine True, if optimization step will be applied to increase the pose accuracy after the RANSAC step
150 * @param iterations Number of maximal RANSAC iterations, with range [1, infinity)
151 * @param sqrPixelErrorThreshold Square pixel error threshold for valid RANSAC candidates, with range (0, infinity)
152 * @param usedIndices Optional vector receiving the indices of all valid correspondences
153 * @param sqrAccuracy Optional resulting average square pixel error
154 * @param weights Optional explicit weights to weight the point correspondences individually
155 * @return True, if succeeded
156 */
157 static inline bool p3p(const HomogenousMatrix4& initialPose, const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, const Vector3& maxPositionOffset = Vector3(Scalar(0.1), Scalar(0.1), Scalar(0.1)), const Scalar maxOrientationOffset = Numeric::deg2rad(10), const unsigned int minValidCorrespondences = 5u, const bool refine = true, const unsigned int iterations = 20u, const Scalar sqrPixelErrorThreshold = Scalar(5 * 5), Indices32* usedIndices = nullptr, Scalar* sqrAccuracy = nullptr, const Scalar* weights = nullptr);
158
159 /**
160 * Calculates a pose including zoom factor using the perspective pose problem with three point correspondences.
161 * The specified point correspondences should be sorted by strength or stability to enhance the pose determination.<br>
162 * This function does not used any apriori information (like e.g. a previous pose).
163 * @param pinholeCamera The pinhole camera object specifying the intrinsic camera parameters
164 * @param objectPointAccessor The accessor providing the 3D object points, at least 4
165 * @param imagePointAccessor The accessor providing the 2D image points, one image point for each object point
166 * @param randomGenerator A random generator object
167 * @param useDistortionParameters True, if the provided image points are distorted and if the camera's distortion parameters should be applied during the pose determination
168 * @param pose Resulting pose
169 * @param zoom Resulting zoom factor matching to the resulting pose, with range (0, infinity)
170 * @param minimalValidCorrespondences Minimal number of valid correspondences
171 * @param refine Determines whether a not linear least square algorithm is used to increase the pose accuracy after the RANSAC step
172 * @param iterations Number of maximal RANSAC iterations, with range [1, infinity)
173 * @param sqrPixelErrorThreshold Square pixel error threshold for valid RANSAC candidates, with range (0, infinity)
174 * @param usedIndices Optional vector receiving the indices of all valid correspondences
175 * @param sqrAccuracy Optional resulting average square pixel error
176 * @param weights Optional explicit weights to weight the point correspondences individually
177 * @return True, if succeeded
178 */
179 static inline bool p3pZoom(const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, Scalar& zoom, const unsigned int minimalValidCorrespondences = 5u, const bool refine = true, const unsigned int iterations = 20u, const Scalar sqrPixelErrorThreshold = Scalar(5 * 5), Indices32* usedIndices = nullptr, Scalar* sqrAccuracy = nullptr, const Scalar* weights = nullptr);
180
181 /**
182 * Calculates a pose including zoom factor, using the perspective pose problem with three point correspondences.
183 * The calculation uses a pose from a previous calculation to increase the robustness.<br>
184 * The specified point correspondences should be sorted by strength or stability to enhance the pose determination.<br>
185 * This function uses a rough pose as apriori information to improve the robustness of the result.
186 * @param initialPose Rough initial pose to increase determination robustness
187 * @param initialZoom Rough initial zoom factor to increase the determination robustness, with range (0, infinity)
188 * @param pinholeCamera The pinhole camera object specifying the intrinsic camera parameters
189 * @param objectPointAccessor The accessor providing the 3D object points, at least 4
190 * @param imagePointAccessor The accessor providing the 2D image points, one image point for each object point
191 * @param randomGenerator A random generator object
192 * @param useDistortionParameters True, if the provided image points are distorted and if the camera's distortion parameters should be applied during the pose determination
193 * @param pose Resulting pose
194 * @param zoom Resulting zoom factor matching to the resulting pose, with range (0, infinity)
195 * @param maxPositionOffset Maximal position offset between initial and final pose for three axis
196 * @param maxOrientationOffset Maximal orientation offset between initial and final pose in radian angle
197 * @param minValidCorrespondences Minimal number of valid correspondences
198 * @param refine True, to apply an optimization step to increase the pose accuracy after the RANSAC step
199 * @param iterations Number of maximal RANSAC iterations, with range [1, infinity)
200 * @param sqrPixelErrorThreshold Square pixel error threshold for valid RANSAC candidates, with range (0, infinity)
201 * @param usedIndices Optional vector receiving the indices of all valid correspondences
202 * @param sqrAccuracy Optional resulting average square pixel error
203 * @param weights Optional explicit weights to weight the point correspondences individually
204 * @return True, if succeeded
205 */
206 static inline bool p3pZoom(const HomogenousMatrix4& initialPose, const Scalar initialZoom, const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, Scalar& zoom, const Vector3& maxPositionOffset = Vector3(Scalar(0.1), Scalar(0.1), Scalar(0.1)), const Scalar maxOrientationOffset = Numeric::deg2rad(10), const unsigned int minValidCorrespondences = 5u, const bool refine = true, const unsigned int iterations = 20u, const Scalar sqrPixelErrorThreshold = Scalar(5 * 5), Indices32* usedIndices = nullptr, Scalar* sqrAccuracy = nullptr, const Scalar* weights = nullptr);
207
208 /**
209 * Determines the 2D line best fitting to a set of given 2D positions.
210 * @param positions The 2D positions for which the line will be determined, at least 2
211 * @param randomGenerator Random generator object
212 * @param line The resulting line best fitting with the given points
213 * @param refine True, to apply an optimization step to increase the accuracy of the line
214 * @param iterations The number of RANSAC iterations, with range [1, infinity)
215 * @param maxSqrError The maximal square error between a direction candidate and a direction from the provided set to count as valid, with range (0, infinity)
216 * @param finalError Optional resulting final average square error between all valid directions and the mean direction
217 * @param usedIndices Optional resulting indices of all used point correspondences
218 * @return True, if succeeded
219 */
220 static bool line(const ConstIndexedAccessor<Vector2>& positions, RandomGenerator& randomGenerator, Line2& line, const bool refine = true, const unsigned int iterations = 20u, const Scalar maxSqrError = Scalar(5 * 5), Scalar* finalError = nullptr, Indices32* usedIndices = nullptr);
221
222 /**
223 * Determines the 2D direction from a set of given 2D directions provided as unit vectors.
224 * @param directions The sets of 2D unit vectors from which the major direction is determined, at least 1
225 * @param randomGenerator A random generator object
226 * @param direction The resulting major direction of the provided set of vectors, will be a unit vector
227 * @param acceptOppositeDirections True, to accept opposite direction (unit vector almost parallel but pointing towards the opposite direction); False, to treat opposite directions as different directions
228 * @param refine True, to apply an optimization step to increase the accuracy of the direction
229 * @param iterations The number of RANSAC iterations, with range [1, infinity)
230 * @param maxAngle The maximal angle between a direction candidate and a direction from the provided set to count as valid, in radian, with range [0, PI)
231 * @param finalError Optional resulting final average angle between all valid directions and the mean direction, this is an approximation only, with range [0, PI)
232 * @param usedIndices Optional resulting indices of all used point correspondences
233 * @return True, if succeeded
234 */
235 static bool direction(const ConstIndexedAccessor<Vector2>& directions, RandomGenerator& randomGenerator, Vector2& direction, const bool acceptOppositeDirections, const bool refine = true, const unsigned int iterations = 20u, const Scalar maxAngle = Numeric::deg2rad(5), Scalar* finalError = nullptr, Indices32* usedIndices = nullptr);
236
237 /**
238 * Determines the 2D translation (offset/translation vector) from a set of given 2D vectors.
239 * @param translations The sets of 2D vectors from which the major translation/offset is determined, at least 1
240 * @param randomGenerator A random generator object
241 * @param translation The resulting major translation of the provided set of vectors
242 * @param refine True, to apply an optimization step to increase the accuracy of the translation
243 * @param iterations The number of RANSAC iterations, with range [1, infinity)
244 * @param maxSqrError The maximal square error between a translation candidate and a translation from the provided set to count as valid, with range (0, infinity)
245 * @param finalError Optional resulting final average square error between all valid translations and the mean translation
246 * @param usedIndices Optional resulting indices of all used point correspondences
247 * @return True, if succeeded
248 */
249 static bool translation(const ConstIndexedAccessor<Vector2>& translations, RandomGenerator& randomGenerator, Vector2& translation, const bool refine = true, const unsigned int iterations = 20u, const Scalar maxSqrError = Scalar(5 * 5), Scalar* finalError = nullptr, Indices32* usedIndices = nullptr);
250
251 /**
252 * Determines the 3DOF rotation of a camera pose for a set of given 2D/3D point correspondences by minimizing the projection error between 3D object points and 2D image points.
253 * @param camera The camera profile defining the projection, must be valid
254 * @param objectPoints The accessor providing the given 3D object points, at least 2
255 * @param imagePoints The accessor providing the given 2D image points, one image point for each 3D object point
256 * @param randomGenerator Random generator object to be used for creating random numbers
257 * @param world_R_camera The resulting camera pose, with default camera pointing towards the negative z-space with y-axis upwards
258 * @param minValidCorrespondences The minimal number of valid correspondences which are necessary for a valid orientation
259 * @param iterations The number of RANSAC iterations, with range [1, infinity)
260 * @param maxSqrError The maximal square pixel error between a projected 3D object point and a 2D image point to count as valid correspondence, with range (0, infinity)
261 * @param finalError Optional resulting final average square pixel error between all valid point correspondences for the resulting orientation
262 * @param usedIndices Optional resulting indices of all used point correspondences, nullptr if not of interest
263 * @param gravityConstraints Optional gravity constraints to guide the pose estimation, nullptr otherwise
264 * @return True, if succeeded
265 */
266 static bool orientation(const AnyCamera& camera, const ConstIndexedAccessor<Vector3>& objectPoints, const ConstIndexedAccessor<Vector2>& imagePoints, RandomGenerator& randomGenerator, Quaternion& world_R_camera, const unsigned int minValidCorrespondences = 5u, const unsigned int iterations = 20u, const Scalar maxSqrError = Scalar(5 * 5), Scalar* finalError = nullptr, Indices32* usedIndices = nullptr, const GravityConstraints* gravityConstraints = nullptr);
267
268 /**
269 * Determines the 3D object point for a set of image points observing the same object point under individual camera poses (with rotational and translational camera motion).
270 * @param camera The camera profile for all camera frames and poses, must be valid
271 * @param world_T_cameras The camera poses of the camera frames in which the image points are located, one for each image point, with default camera pointing towards the negative z-space with y-axis upwards, at least two
272 * @param imagePoints The image points observing the 3D object point, one image point for each pose
273 * @param randomGenerator Random generator object to be used for creating random numbers
274 * @param objectPoint Resulting 3D object point defined in world
275 * @param iterations Number of RANSAC iterations, with range [1, infinity)
276 * @param maximalSqrError The maximal square pixel error between a projected object point and an image point, with range [0, infinity)
277 * @param minValidCorrespondences The minimal number of image points that have a projected pixel error smaller than 'maximalError', with range [2, correspondences]
278 * @param onlyFrontObjectPoint True, if the resulting object point must lie in front of the camera
279 * @param refinementEstimator An robust estimator to invoke an optimization step to increase the accuracy of the resulting position, ET_INVALID to avoid the refinement
280 * @param finalRobustError Optional the resulting final robust error
281 * @param usedIndices Optional resulting indices of valid image points
282 * @return True, if succeeded
283 */
284 static inline bool objectPoint(const AnyCamera& camera, const ConstIndexedAccessor<HomogenousMatrix4>& world_T_cameras, const ConstIndexedAccessor<Vector2>& imagePoints, RandomGenerator& randomGenerator, Vector3& objectPoint, const unsigned int iterations = 20u, const Scalar maximalSqrError = Scalar(3 * 3), const unsigned int minValidCorrespondences = 2u, const bool onlyFrontObjectPoint = true, const Estimator::EstimatorType refinementEstimator = Estimator::ET_SQUARE, Scalar* finalRobustError = nullptr, Indices32* usedIndices = nullptr);
285
286 /**
287 * Determines the 3D object point for a set of image points observing the same object point under individual camera poses (with rotational and translational camera motion), while each camera pose has an own camera profile.
288 * @param cameras The camera profiles for all camera frames and poses, must be valid
289 * @param world_T_cameras The camera poses of the camera frames in which the image points are located, one for each image point, with default camera pointing towards the negative z-space with y-axis upwards, at least two
290 * @param imagePoints The image points observing the 3D object point, one image point for each pose
291 * @param randomGenerator Random generator object to be used for creating random numbers
292 * @param objectPoint Resulting 3D object point, defined in world
293 * @param iterations Number of RANSAC iterations, with range [1, infinity)
294 * @param maximalSqrError The maximal square pixel error between a projected object point and an image point, with range [0, infinity)
295 * @param minValidCorrespondences The minimal number of image points that have a projected pixel error smaller than 'maximalError', with range [2, correspondences]
296 * @param onlyFrontObjectPoint True, if the resulting object point must lie in front of the camera
297 * @param refinementEstimator An robust estimator to invoke an optimization step to increase the accuracy of the resulting position, ET_INVALID to avoid the refinement
298 * @param finalRobustError Optional the resulting final robust error
299 * @param usedIndices Optional resulting indices of valid image points
300 * @return True, if succeeded
301 */
302 static bool objectPoint(const ConstIndexedAccessor<const AnyCamera*>& cameras, const ConstIndexedAccessor<HomogenousMatrix4>& world_T_cameras, const ConstIndexedAccessor<Vector2>& imagePoints, RandomGenerator& randomGenerator, Vector3& objectPoint, const unsigned int iterations = 20u, const Scalar maximalSqrError = Scalar(3 * 3), const unsigned int minValidCorrespondences = 2u, const bool onlyFrontObjectPoint = true, const Estimator::EstimatorType refinementEstimator = Estimator::ET_SQUARE, Scalar* finalRobustError = nullptr, Indices32* usedIndices = nullptr);
303
304 /**
305 * Determines the 3D object point for a set of image points observing the same object point under individual camera poses (with rotational camera motion only).
306 * The center position of each camera is located at the origin of the coordinate system.
307 * @param camera The camera profile defining the projection for all camera frames and poses, must be valid
308 * @param world_R_cameras The camera orientations of the camera frames in which the image points are located, transforming cameras to world, with default camera pointing towards the negeative z-space with y-axis upwards, at least two
309 * @param imagePoints The image points observing the 3D object point, one image point for each pose
310 * @param randomGenerator Random generator object to be used for creating random numbers
311 * @param objectPoint The resulting 3D object point
312 * @param objectPointDistance The distance between the origin and a resulting object point, with range (0, infinity)
313 * @param iterations Number of RANSAC iterations, with range [1, infinity)
314 * @param maximalError The maximal square pixel error between a projected object point and an image point, with range (0, infinity)
315 * @param minValidCorrespondences The minimal number of image points that have a projected pixel error smaller than 'maximalError', with range [2, correspondences]
316 * @param onlyFrontObjectPoint True, if the resulting object point must lie in front of the camera
317 * @param refinementEstimator An robust estimator to invoke an optimization step to increase the accuracy of the resulting position, ET_INVALID to avoid the refinement
318 * @param finalError Optional the resulting final error
319 * @param usedIndices Optional resulting indices of valid image points
320 * @return True, if succeeded
321 */
322 static bool objectPoint(const AnyCamera& camera, const ConstIndexedAccessor<SquareMatrix3>& world_R_cameras, const ConstIndexedAccessor<Vector2>& imagePoints, RandomGenerator& randomGenerator, Vector3& objectPoint, const Scalar objectPointDistance, const unsigned int iterations = 20u, const Scalar maximalError = Scalar(3 * 3), const unsigned int minValidCorrespondences = 2u, const bool onlyFrontObjectPoint = true, const Estimator::EstimatorType refinementEstimator = Estimator::ET_SQUARE, Scalar* finalError = nullptr, Indices32* usedIndices = nullptr);
323
324 /**
325 * Determines a 3D plane best matching to a set of given 3D object points.
326 * @param objectPoints The 3D object points for which the best fitting plane will be determined, at least 3
327 * @param randomGenerator Random generator object to be used for creating random numbers
328 * @param plane Resulting 3D plane
329 * @param iterations Number of RANSAC iterations, with range [1, infinity)
330 * @param medianDistanceFactor The factor which is used to defined the maximal distance between an object point on the plane to count as valid, the factor is multiplied with the median distance between all object points and the median object point, with range [0, infinity), -1 to accept all object points as valid
331 * @param minValidCorrespondences The minimal number of image points that have an error smaller than the determine median-based threshold, with range [2, correspondences]
332 * @param refinementEstimator An robust estimator to invoke an optimization step to increase the accuracy of the resulting position, ET_INVALID to avoid the refinement
333 * @param finalError Optional the resulting final error
334 * @param usedIndices Optional resulting indices of valid object points
335 * @return True, if succeeded
336 */
337 static bool plane(const ConstIndexedAccessor<Vector3>& objectPoints, RandomGenerator& randomGenerator, Plane3& plane, const unsigned int iterations = 20u, const Scalar medianDistanceFactor = Scalar(0.1), const unsigned int minValidCorrespondences = 3u, const Estimator::EstimatorType refinementEstimator = Estimator::ET_SQUARE, Scalar* finalError = nullptr, Indices32* usedIndices = nullptr);
338
339 /**
340 * Optimizes an already known 3D plane by minimizing the error between the plane and a set of given 3D object points.
341 * @param initialPlane The already known initial plane which will be optimized, must be valid
342 * @param objectPoints The 3D object points for which the best fitting plane will be determined, at least 3
343 * @param randomGenerator Random generator object to be used for creating random numbers
344 * @param plane Resulting 3D plane
345 * @param iterations Number of RANSAC iterations, with range [1, infinity)
346 * @param maximalNormalOrientationOffset The maximal angle between the normal of the initial plane and the final optimized plane in radian, with range [0, PI/2]
347 * @param medianDistanceFactor The factor which is used to defined the maximal distance between an object point on the plane to count as valid, the factor is multiplied with the median distance between all object points and the initial plane, with range [0, infinity), -1 to accept all object points as valid
348 * @param minValidCorrespondences The minimal number of image points that have an error smaller than the determine median-based threshold, with range [2, correspondences]
349 * @param refinementEstimator A robust estimator to invoke an optimization step to increase the accuracy of the resulting position, ET_INVALID to avoid the refinement
350 * @param finalError Optional resulting final error
351 * @param usedIndices Optional resulting indices of valid object points
352 * @return True, if succeeded
353 */
354 static bool plane(const Plane3& initialPlane, const ConstIndexedAccessor<Vector3>& objectPoints, RandomGenerator& randomGenerator, Plane3& plane, const unsigned int iterations = 20u, const Scalar maximalNormalOrientationOffset = Numeric::deg2rad(30), const Scalar medianDistanceFactor = Scalar(0.1), const unsigned int minValidCorrespondences = 3u, const Estimator::EstimatorType refinementEstimator = Estimator::ET_SQUARE, Scalar* finalError = nullptr, Indices32* usedIndices = nullptr);
355
356 /**
357 * Determines the fundamental matrix for given image point correspondences for two stereo images.
358 * @param leftImagePoints The left image points, at least 8, must be valid
359 * @param rightImagePoints The right image points, one for each left image point, must be valid
360 * @param correspondences The number of point correspondences, with range [testCandidates, infinity)
361 * @param randomGenerator Random generator object to be used for creating random numbers
362 * @param right_F_left The resulting fundamental matrix
363 * @param testCandidates The number of candidates used in each RANSAC iteration, with range [8, correspondences]
364 * @param iterations The number of RANSAC iterations, with range [1, infinity)
365 * @param maxScalarProduct The maximal scalar product for valid point correspondences, with range [0, infinity)
366 * @param usedIndices Optional resutling indices of the used point correspondences, nullptr if not of interest
367 * @return True, if succeeded
368 * @see extrinsicMatrix(), Geometry::EpipolarGeometry::fundamental2essential().
369 */
370 static bool fundamentalMatrix(const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator& randomGenerator, SquareMatrix3& right_F_left, const size_t testCandidates = 8, const unsigned int iterations = 20u, const Scalar maxScalarProduct = Scalar(0.001), Indices32* usedIndices = nullptr);
371
372 /**
373 * Calculates the extrinsic camera matrix by given point correspondences for two stereo images.
374 * The extrinsic matrix can be determined up to a scale factor for the translation vector.<br>
375 * The left camera is expected to be located in the origin while looking towards the negative z-axis with y-axis as up vector.<br>
376 * The resulting transformation defines the extrinsic camera matrix for the right camera.
377 * @param leftCamera Left camera corresponding to the left image points
378 * @param rightCamera Right camera corresponding to the right image points
379 * @param leftImagePoints Left image points (each point corresponds to a right image point)
380 * @param rightImagePoints Right image points (each point corresponds to a left image point)
381 * @param correspondences Number of point correspondences, with range [testCandidates, infinity)
382 * @param transformation Resulting extrinsic camera transformation matrix which transforms points lying in the right camera coordinate system into points lying in the left camera coordinate system
383 * @param testCandidates Number of candidates used in each RANSAC iteration, with range [8, correspondences]
384 * @param iterations Number of RANSAC iterations, with range [1, infinity)
385 * @param squarePixelErrorThreshold Maximal square pixel error of a valid projection of a 3D point onto the 2D image plane, with range (0, infinity)
386 * @param maxTranslation Optional maximal resulting translation bounding box vector, if defined should have a maximal expansion of +/- 1 in each axis
387 * @param maxRotation Optional maximal resulting rotation in radian
388 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
389 * @return True, if succeeded
390 * @see fundamentalMatrix().
391 */
392 static bool extrinsicMatrix(const PinholeCamera& leftCamera, const PinholeCamera& rightCamera, const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, HomogenousMatrix4& transformation, const unsigned int testCandidates = 8u, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(9), const Box3& maxTranslation = Box3(), const Scalar maxRotation = Numeric::pi(), Indices32* usedIndices = nullptr);
393
394 /**
395 * Calculates the homography between two images transforming the given image points between two images.
396 * This function needs bijective correspondences (each left image points matches exactly with one unique right image points).<br>
397 * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
398 * Beware: This function is intended for prototyping purposes only. When binary size matters, please use the corresponding function using template parameters instead of 'refine' and 'useSVD'.
399 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image, must be valid
400 * @param rightImagePoints Image points in the right camera, one for each point in the left frame, must be valid
401 * @param correspondences Number of points correspondences, with range [4, infinity)
402 * @param randomGenerator Random generator object to be used for creating random numbers
403 * @param homography Resulting homography for the given image points
404 * @param testCandidates Number of candidates used in each RANSAC iterations, with range [4, correspondences]
405 * @param refine True, to apply a non-linear least square optimization to increase the transformation accuracy after the RANSAC step
406 * @param iterations Number of RANSAC iterations, with range [1, infinity)
407 * @param squarePixelErrorThreshold Maximal square pixel error between a right point and a transformed left point so that a point correspondence counts as valid, with range (0, infinity)
408 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
409 * @param worker Optional worker object to distribute the computation
410 * @param useSVD True, to use the slower SVD approach (i.e., Homography::homographyMatrixSVD); False, to use the two-step approach (i.e., Homography::homographyMatrixLinearWithOptimizations)
411 * @return True, if succeeded
412 * @see homographyMatrix<tRefine, tUseSVD>(), Geometry::Homography::homographyMatrix(), homographyMatrixForNonBijectiveCorrespondences().
413 */
414 static inline bool homographyMatrix(const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator& randomGenerator, SquareMatrix3& homography, const unsigned int testCandidates = 8u, const bool refine = true, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(9), Indices32* usedIndices = nullptr, Worker* worker = nullptr, const bool useSVD = true);
415
416 /**
417 * Calculates the homography between two images transforming the given image points between two images.
418 * This function can be applied if the given correspondences are not bijective.<br>
419 * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
420 * Beware: This function is intended for prototyping purposes only. When binary size matters, please use the corresponding function using template parameters instead of 'refine' and 'useSVD'.
421 * @param leftImagePoints Image points in the left camera, must be valid
422 * @param numberLeftImagePoints the number of given left image points, with range [4, infinity)
423 * @param rightImagePoints Image points in the right camera, must be valid
424 * @param numberRightImagePoints The number of given right image points, with range [4, infinity)
425 * @param correspondences The pairs defining the non-bijective correspondences, with range [0, numberLeftImagePoints - 1]x[0, numberRightImagePoints - 1], must be valid
426 * @param numberCorrespondences The number of given correspondence pairs, with range [4, infinity)
427 * @param randomGenerator Random generator object to be used for creating random numbers
428 * @param right_H_left Resulting homography for the given image points, (rightPoint = right_H_left * leftPoint)
429 * @param testCandidates Number of candidates used in each RANSAC iterations, with range [4, correspondences]
430 * @param refine True, to apply a non-linear least square optimization to increase the transformation accuracy after the RANSAC step
431 * @param iterations Number of RANSAC iterations, with range [1, infinity)
432 * @param squarePixelErrorThreshold Maximal square pixel error between a right point and a transformed left point so that a point correspondence counts as valid, with range (0, infinity)
433 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
434 * @param worker Optional worker object to distribute the computation
435 * @param useSVD True, to use the slower SVD approach (i.e., Homography::homographyMatrixSVD); False, to use the two-step approach (i.e., Homography::homographyMatrixLinearWithOptimizations)
436 * @return True, if succeeded
437 * @see homographyMatrixForNonBijectiveCorrespondences<tRefine, tUseSVD>(), homographyMatrix().
438 */
439 static inline bool homographyMatrixForNonBijectiveCorrespondences(const Vector2* leftImagePoints, const size_t numberLeftImagePoints, const Vector2* rightImagePoints, const size_t numberRightImagePoints, const IndexPair32* correspondences, const size_t numberCorrespondences, RandomGenerator& randomGenerator, SquareMatrix3& right_H_left, const unsigned int testCandidates = 8u, const bool refine = true, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(9), Indices32* usedIndices = nullptr, Worker* worker = nullptr, const bool useSVD = true);
440
441 /**
442 * Calculates the homography between two images transforming the given image points between two images.
443 * This function needs bijective correspondences (each left image points matches exactly with one unique right image points).<br>
444 * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
445 * This function applies template parameters for refine and useSVD. Thus, this function will create smaller binary sizes.
446 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
447 * @param rightImagePoints Image points in the right camera, one for each point in the left frame
448 * @param correspondences Number of points correspondences, with range [4, infinity)
449 * @param randomGenerator Random generator object to be used for creating random numbers
450 * @param homography Resulting homography for the given image points
451 * @param testCandidates Number of candidates used in each RANSAC iterations, with range [4, correspondences]
452 * @param iterations Number of RANSAC iterations, with range [1, infinity)
453 * @param squarePixelErrorThreshold Maximal square pixel error between a right point and a transformed left point so that a point correspondence counts as valid, with range (0, infinity)
454 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
455 * @param worker Optional worker object to distribute the computation
456 * @return True, if succeeded
457 * @tparam tRefine True, to apply a non-linear least square optimization to increase the transformation accuracy after the RANSAC step
458 * @tparam tUseSVD True, to use the slower SVD approach (i.e., Homography::homographyMatrixSVD); False, to use the two-step approach (i.e., Homography::homographyMatrixLinearWithOptimizations)
459 * @see homographyMatrix(), Geometry::Homography::homographyMatrix().
460 */
461 template <bool tRefine, bool tUseSVD>
462 static bool homographyMatrix(const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator& randomGenerator, SquareMatrix3& homography, const unsigned int testCandidates = 8u, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(9), Indices32* usedIndices = nullptr, Worker* worker = nullptr);
463
464 /**
465 * Calculates the homography between two images transforming the given image points between two images.
466 * This function can be applied if the given correspondences are not bijective.<br>
467 * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
468 * This function applies template parameters for refine and useSVD. Thus, this function will create smaller binary sizes.
469 * @param leftImagePoints Image points in the left camera, must be valid
470 * @param numberLeftImagePoints the number of given left image points, with range [4, infinity)
471 * @param rightImagePoints Image points in the right camera, must be valid
472 * @param numberRightImagePoints The number of given right image points, with range [4, infinity)
473 * @param correspondences The pairs defining the non-bijective correspondences, with range [0, numberLeftImagePoints - 1]x[0, numberRightImagePoints - 1], must be valid
474 * @param numberCorrespondences The number of given correspondence pairs, with range [4, infinity)
475 * @param randomGenerator Random generator object to be used for creating random numbers
476 * @param right_H_left Resulting homography for the given image points, (rightPoint = right_H_left * leftPoint)
477 * @param testCandidates Number of candidates used in each RANSAC iterations, with range [4, correspondences]
478 * @param iterations Number of RANSAC iterations, with range [1, infinity)
479 * @param squarePixelErrorThreshold Maximal square pixel error between a right point and a transformed left point so that a point correspondence counts as valid, with range (0, infinity)
480 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
481 * @param worker Optional worker object to distribute the computation
482 * @return True, if succeeded
483 * @tparam tRefine True, to apply a non-linear least square optimization to increase the transformation accuracy after the RANSAC step
484 * @tparam tUseSVD True, to use the slower SVD approach (i.e., Homography::homographyMatrixSVD); False, to use the two-step approach (i.e., Homography::homographyMatrixLinearWithOptimizations)
485 * @see homographyMatrixForNonBijectiveCorrespondences().
486 */
487 template <bool tRefine, bool tUseSVD>
488 static bool homographyMatrixForNonBijectiveCorrespondences(const Vector2* leftImagePoints, const size_t numberLeftImagePoints, const Vector2* rightImagePoints, const size_t numberRightImagePoints, const IndexPair32* correspondences, const size_t numberCorrespondences, RandomGenerator& randomGenerator, SquareMatrix3& right_H_left, const unsigned int testCandidates = 8u, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(9), Indices32* usedIndices = nullptr, Worker* worker = nullptr);
489
490 /**
491 * Calculates four homographies between two images transforming the given image points between two images.
492 * The resulting homographies transforms image points defined in the left image to image points defined in the right image (rightPoint = H[i] * leftPoint).<br>
493 * Four homographies are determined, one homography for each quadrant in the frame allowing to address minor distortions in the frames.<br>
494 * The quadrant order of the homographies is as follows: top left, top right, bottom left, bottom right.
495 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
496 * @param rightImagePoints Image points in the right camera
497 * @param correspondences Number of points correspondences
498 * @param leftQuadrantCenter The center of the four quadrants in the left frame (this may be the center of the left frame), with range [0, leftImageWidth)x[0, leftImageHeight)
499 * @param randomGenerator Random generator object to be used for creating random numbers
500 * @param homographies Resulting four homographies for the given image points
501 * @param testCandidates Number of candidates used in each RANSAC iterations, with range [4, correspondences]
502 * @param iterations Number of RANSAC iterations, with range [1, infinity)
503 * @param squarePixelErrorThreshold Maximal square pixel error between a right point and a transformed left point so that a point correspondence counts as valid, with range (0, infinity)
504 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
505 * @param worker Optional worker object to distribute the computation
506 * @return True, if succeeded
507 * @see Geometry::Homography::homographyMatrix().
508 */
509 static bool homographyMatrices(const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, const Vector2& leftQuadrantCenter, RandomGenerator& randomGenerator, SquareMatrix3 homographies[4], const unsigned int testCandidates = 8u, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(9), Indices32* usedIndices = nullptr, Worker* worker = nullptr);
510
511 /**
512 * Calculates inverted flipped camera poses (up to a common 3d projection transformation) for image point corresponds between images from multiple views.
513 * @param imagePointsPerPose Image points per view (at least 3 views and at least 6 point correspondences)
514 * @param posesIF Resulting camera projection matrices per view (inverted flipped)
515 * @param iterations Number of RANSAC iterations, with range [1, infinity)
516 * @param squarePixelErrorThreshold Maximal square pixel error of a valid projection of a 3D point onto the 2D image plane, with range (0, infinity)
517 * @param objectPointsIF Optional vector which will receive the object points of the image point correspondences, if defined
518 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
519 * @param worker Optional worker object to distribute the computation
520 * @return True, if succeeded
521 * @see Geometry::MultipleViewGeometry::projectiveReconstructionFrom6PointsIF().
522 */
523 static bool projectiveReconstructionFrom6PointsIF(const ConstIndexedAccessor<Vectors2>& imagePointsPerPose, NonconstIndexedAccessor<HomogenousMatrix4>* posesIF, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(9), NonconstArrayAccessor<Vector3>* objectPointsIF = nullptr, Indices32* usedIndices = nullptr, Worker* worker = nullptr);
524
525 /**
526 * Determines the camera calibration for several given camera calibration patterns, each pattern object holds the 2D/3D point correspondences for a planar calibration pattern observed from an individual viewing position.
527 * The camera profile must be constant (must be identical) for all given calibration patterns.
528 *
529 * This calibration function uses RANSAC iterations to find the best calibration for the given point correspondence sets.<br>
530 * Thus, only a subset of the given correspondence sets are used for camera determination and then tested against the entire set.<br>
531 * The best matching subset is then used to create a calibration for all valid calibration patterns.
532 * @param width The width of the camera frame in pixel, with range [1, infinity)
533 * @param height The height of the camera frame in pixel, with range [1, infinity)
534 * @param calibrationPatterns The detected calibration patterns used for calibration, at least 4
535 * @param calibrationPatternBoxSize Size of one calibration pattern box in a specific unit (e.g., meter), with ranges (0, infinity)x(0, infinity)
536 * @param testCandidates Number of candidates used in each RANSAC iteration, with range [4, correspondences]
537 * @param pinholeCamera Resulting camera holding all extracted calibration information like e.g. intrinsic camera and distortion parameters
538 * @param iterations Number of RANSAC iterations, with range [1, infinity)
539 * @param sqrAccuracy Optional accuracy value receiving the average square pixel error, if defined
540 * @param worker Optional worker object to distribute the computation to several CPU cores
541 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
542 * @return True, if succeeded
543 */
544 static bool determineCameraCalibrationPlanar(const unsigned int width, const unsigned int height, const CameraCalibration::Patterns& calibrationPatterns, const Vector2& calibrationPatternBoxSize, const unsigned int testCandidates, PinholeCamera& pinholeCamera, const unsigned int iterations = 20u, Scalar* sqrAccuracy = nullptr, Worker* worker = nullptr, Indices32* usedIndices = nullptr);
545
546 /**
547 * Performs execution of a camera calibration for a given subset of the entire data provided.
548 * The calibration is done for several individual groups of 3D object points all lying on the same 3D plane and corresponding 2D image points.
549 * The individual groups of image points can e.g., be the result of individual images of a calibration pattern observed from different viewing positions.
550 * @param width The width of the camera image in pixel, with range [1, infinity)
551 * @param height The height of the camera image in pixel, with range [1, infinity)
552 * @param objectPointGroups The groups of object points (all points lie in the Z == 0 plane), each group has a corresponding group of image points
553 * @param imagePointGroups The groups of image points, one group for each corresponding group of object points
554 * @param indices Indices defining the subset of given image and object points to be used for camera calibration calculation
555 * @param pinholeCamera Resulting camera profile holding all extracted calibration information like e.g. intrinsic camera and distortion parameters
556 * @param sqrAccuracy Optional resulting average square projection error in pixel accuracy, if the iteration fails the accuracy value is untouched
557 */
558 static void determineCameraCalibrationPlanarIteration(const unsigned int width, const unsigned int height, const ConstIndexedAccessor<Vectors3>* objectPointGroups, const ConstIndexedAccessor<Vectors2>* imagePointGroups, Indices32* indices, PinholeCamera* pinholeCamera, Scalar* sqrAccuracy);
559
560 /**
561 * Calculates the affine transformation (6DOF - translation, rotation, scale, aspect ratio, shear) between two sets of 2D image points.
562 * @param leftImagePoints The image points in the left image, must be valid
563 * @param rightImagePoints The image points in the right image, one for each point in the left image, must be valid
564 * @param correspondences The number of points correspondences, with range [3, infinity)
565 * @param randomGenerator The random generator to be used
566 * @param right_A_left The resulting affine transformation matrix transforming left to right image points
567 * @param testCandidates The number of candidates used in each RANSAC iterations, with range [3, correspondences]
568 * @param iterations The number of RANSAC iterations, with range [1, infinity)
569 * @param squarePixelErrorThreshold The maximal square pixel error between two corresponding image points to count as valid, with range (0, infinity)
570 * @param usedIndices Optional resulting indices of the used point correspondences, if defined
571 * @param worker Optional worker object to distribute the computation
572 * @return True, if succeeded
573 * @see Homography::affineMatrix().
574 */
575 static bool affineMatrix(const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator& randomGenerator, SquareMatrix3& right_A_left, const unsigned int testCandidates = 6u, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(3 * 3), Indices32* usedIndices = nullptr, Worker* worker = nullptr);
576
577 /**
578 * Calculates the similarity transformation (4DOF - translation, rotation, scale) between two images transforming the given image points between two images.
579 * The resulting similarity transforms image points defined in the left image to image points defined in the right image (rightPoint = S * leftPoint).
580 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
581 * @param rightImagePoints Image points in the right camera
582 * @param correspondences Number of points correspondences
583 * @param randomGenerator Random generator object to be used for creating random numbers
584 * @param similarity Resulting similarity for the given image points so that (rightPoint = S * leftPoint) holds
585 * @param testCandidates Number of candidates used in each RANSAC iterations, with range [2, correspondences]
586 * @param iterations Number of RANSAC iterations, with range [1, infinity)
587 * @param squarePixelErrorThreshold The maximal square pixel error, with range (0, infinity)
588 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
589 * @param worker Optional worker object to distribute the computation
590 * @return True, if succeeded
591 * @see Geometry::Homography::similarityMatrix().
592 */
593 static bool similarityMatrix(const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator& randomGenerator, SquareMatrix3& similarity, const unsigned int testCandidates = 4u, const unsigned int iterations = 20u, const Scalar squarePixelErrorThreshold = Scalar(9), Indices32* usedIndices = nullptr, Worker* worker = nullptr);
594
595 /**
596 * Determines the 6-DOF object transformation between world and object so that the transformation fits with two observations in two images (left and right stereo image).
597 * @param anyCameraA The camera profile of the first camera, must be valid
598 * @param anyCameraB the camera profile of the second camera, must be valid
599 * @param world_T_cameraA The transformation between first camera and world, must be valid
600 * @param world_T_cameraB The transformation between second camera and world, must be valid
601 * @param objectPointsA The 3D object points of the observation of the object in the first camera, defined in the coordinate system of the object
602 * @param objectPointsB The 3D object points of the observation of the object in the second camera, defined in the coordinate system of the object
603 * @param imagePointsA The 2D image points of the observation of the object in the first camera, one for each 3D object point
604 * @param imagePointsB The 2D image points of the observation of the object in the second camera, one for each 3D object point
605 * @param randomGenerator Random generator object to be used
606 * @param world_T_object The resulting transformation between object and world
607 * @param minimalValidCorrespondences Minimal number of correspondences so that the resulting transformation counts as valid, with range [4, objectPointsA.size() + objectPointsB.size()]
608 * @param refine True, to apply a non-linear least square optimization to increase the transformation accuracy after the RANSAC step
609 * @param iterations The number of RANSAC iteration to be applied, with range [1, infinity)
610 * @param sqrPixelErrorThreshold Square projection error for valid 2D/3D correspondences, with range [0, infinity)
611 * @param usedIndicesA Optional resulting indices of valid correspondences from the first camera
612 * @param usedIndicesB Optional resulting indices of valid correspondences from the second camera
613 * @param sqrAccuracy Optional resulting average square pixel error
614 * @param allowMonoObservation True, to allow that the object is visible in one of both camera frames only; False, to fail in case the object is visible in only one camera frame
615 * @return True, if succeeded
616 */
617 static bool objectTransformationStereo(const AnyCamera& anyCameraA, const AnyCamera& anyCameraB, const HomogenousMatrix4& world_T_cameraA, const HomogenousMatrix4& world_T_cameraB, const ConstIndexedAccessor<Vector3>& objectPointsA, const ConstIndexedAccessor<Vector3>& objectPointsB, const ConstIndexedAccessor<Vector2>& imagePointsA, const ConstIndexedAccessor<Vector2>& imagePointsB, RandomGenerator& randomGenerator, HomogenousMatrix4& world_T_object, const unsigned int minimalValidCorrespondences = 5u, const bool refine = true, const unsigned int iterations = 20u, const Scalar sqrPixelErrorThreshold = Scalar(5 * 5), Indices32* usedIndicesA = nullptr, Indices32* usedIndicesB = nullptr, Scalar* sqrAccuracy = nullptr, const bool allowMonoObservation = true);
618
619 private:
620
621 /**
622 * Calculates a camera pose using the perspective pose problem with three point correspondences.
623 * The calculation can use a rough camera pose (e.g., from a previous camera frame) to increase the robustness.
624 * @param world_T_roughCamera Optional already known rough camera pose, transforming rough camera points to world points, with default camera pointing towards the negative z-space with y-axis upwards, nullptr if unknown
625 * @param camera The camera profile defining the project, must be valid
626 * @param objectPointAccessor The accessor providing the 3D object points, each corresponding to one image point, at least four
627 * @param imagePointAccessor The accessor providing the 2D image points, each corresponding to one object point, at least four
628 * @param randomGenerator The random generator to be used
629 * @param world_T_camera The resulting camera pose, transforming camera points to world points, with default camera pointing towards the negative z-space with y-axis upwards, must be valid
630 * @param maxPositionOffset Optional maximal position offset between initial and final pose for three axis
631 * @param maxOrientationOffset Optional maximal orientation offset between initial and final pose in radian angle
632 * @param minValidCorrespondences Minimal number of valid correspondences
633 * @param refine Determines whether a not linear least square algorithm is used to increase the pose accuracy after the RANSAC step
634 * @param iterations Number of maximal RANSAC iterations, with range [1, infinity)
635 * @param sqrPixelErrorThreshold Square pixel error threshold for valid RANSAC candidates
636 * @param usedIndices Optional vector receiving the indices of all valid correspondences
637 * @param sqrAccuracy Optional resulting average square pixel error, with range [0, infinity)
638 * @param weights Optional weights to weight the individual point correspondences individually, nullptr to use the same weight for all point correspondences
639 * @return True, if succeeded
640 */
641 static bool p3p(const HomogenousMatrix4* world_T_roughCamera, const AnyCamera& camera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, HomogenousMatrix4& world_T_camera, const Vector3* maxPositionOffset, const Scalar* maxOrientationOffset, const unsigned int minValidCorrespondences, const bool refine, const unsigned int iterations, const Scalar sqrPixelErrorThreshold, Indices32* usedIndices, Scalar* sqrAccuracy, const Scalar* weights);
642
643 /**
644 * Calculates a pose including zoom factor using the perspective pose problem with three point correspondences.
645 * The calculation can use a pose from a previous calculation to increase the robustness.<br>
646 * The specified point correspondences should be sorted by strength or stability to enhance the pose determination.<br>
647 * This function may use apriori information (like e.g. a previous pose).
648 * @param initialPose Optional rough initial pose to increase determination robustness
649 * @param initialZoom Optional rough initial zoom to increase determination robustness
650 * @param pinholeCamera The pinhole camera object specifying the intrinsic camera parameters
651 * @param objectPointAccessor The accessor providing the 3D object points, each corresponding to one image point, at least four
652 * @param imagePointAccessor The accessor providing the 2D image points, each corresponding to one object point, at least four
653 * @param randomGenerator A random generator object
654 * @param useDistortionParameters True, to use the distortion parameters of the camera profile; False, otherwise
655 * @param pose Resulting pose
656 * @param zoom Resulting zoom factor
657 * @param maxPositionOffset Optional maximal position offset between initial and final pose for three axis
658 * @param maxOrientationOffset Optional maximal orientation offset between initial and final pose in radian angle
659 * @param minValidCorrespondences Minimal number of valid correspondences
660 * @param refine Determines whether a not linear least square algorithm is used to increase the pose accuracy after the RANSAC step
661 * @param iterations Number of maximal RANSAC iterations, with range [1, infinity)
662 * @param sqrPixelErrorThreshold Square pixel error threshold for valid RANSAC candidates
663 * @param usedIndices Optional vector receiving the indices of all valid correspondences
664 * @param sqrAccuracy Optional resulting average square pixel error
665 * @param weights Optional weights for each point correspondence
666 * @return True, if succeeded
667 */
668 static bool p3pZoom(const HomogenousMatrix4* initialPose, const Scalar* initialZoom, const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, Scalar& zoom, const Vector3* maxPositionOffset, const Scalar* maxOrientationOffset, const unsigned int minValidCorrespondences = 5u, const bool refine = true, const unsigned int iterations = 20u, const Scalar sqrPixelErrorThreshold = Scalar(5 * 5), Indices32* usedIndices = nullptr, Scalar* sqrAccuracy = nullptr, const Scalar* weights = nullptr);
669
670 /**
671 * Calculates the geometry transformation between two images transforming the given image points between two images.
672 * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = M * leftPoint).
673 * @param geometricTransformFunction The pointer to the geometric transformation function to be applied, must be valid
674 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
675 * @param rightImagePoints Image points in the right camera
676 * @param correspondences Number of points correspondences
677 * @param randomGenerator Random generator object to be used for creating random numbers
678 * @param transformMatrix Resulting homography for the given image points
679 * @param testCandidates Number of candidates used in each RANSAC iterations
680 * @param iterations Number of RANSAC iterations, with range [1, infinity)
681 * @param squarePixelErrorThreshold The maximal square pixel error, with range (0, infinity)
682 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
683 * @param worker Optional worker object to distribute the computation
684 * @return True, if succeeded
685 */
686 static bool geometricTransform(const GeometricTransformFunction geometricTransformFunction, const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator& randomGenerator, SquareMatrix3& transformMatrix, const unsigned int testCandidates, const unsigned int iterations, const Scalar squarePixelErrorThreshold, Indices32* usedIndices, Worker* worker);
687
688 /**
689 * Calculates the geometry transformation between two images transforming the given image points between two images.
690 * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = M * leftPoint).
691 * @param geometricTransformFunction The pointer to the geometric transformation function to be applied, must be valid
692 * @param leftImagePoints Image points in the left camera, must be valid
693 * @param numberLeftImagePoints The number of given left image points, with range [1, infinity)
694 * @param rightImagePoints Image points in the right camera, must be valid
695 * @param numberRightImagePoints The number of given right image points, with range [1, infinity)
696 * @param correspondences The pairs defining the non-bijective correspondences, with range [0, numberLeftImagePoints - 1]x[0, numberRightImagePoints - 1], must be valid
697 * @param numberCorrespondences The number of given correspondence pairs, with range [1, infinity)
698 * @param randomGenerator Random generator object to be used for creating random numbers
699 * @param transformMatrix Resulting homography for the given image points
700 * @param testCandidates Number of candidates used in each RANSAC iterations
701 * @param iterations Number of RANSAC iterations, with range [1, infinity)
702 * @param squarePixelErrorThreshold The maximal square pixel error, with range (0, infinity)
703 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
704 * @param worker Optional worker object to distribute the computation
705 * @return True, if succeeded
706 */
707 static bool geometricTransformForNonBijectiveCorrespondences(const GeometricTransformFunction geometricTransformFunction, const Vector2* leftImagePoints, const size_t numberLeftImagePoints, const Vector2* rightImagePoints, const size_t numberRightImagePoints, const IndexPair32* correspondences, const size_t numberCorrespondences, RandomGenerator& randomGenerator, SquareMatrix3& transformMatrix, const unsigned int testCandidates, const unsigned int iterations, const Scalar squarePixelErrorThreshold, Indices32* usedIndices, Worker* worker);
708
709 /**
710 * Internal function to calculate the geometry transformation between two images transforming the projected planar object points between the two images.
711 * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = M * leftPoint).
712 * @param geometricTransformFunction The pointer to the geometric transformation function to be applied, must be valid
713 * @param leftImagePoints Image points in the left camera, each point corresponds to one point in the right image
714 * @param rightImagePoints Image points in the right camera
715 * @param correspondences Number of points correspondences
716 * @param randomGenerator Random generator object to be used for creating random numbers
717 * @param transformMatrix Resulting homography for the given image points
718 * @param testCandidates Number of candidates used in each RANSAC iterations, with range [1, correspondences]
719 * @param squarePixelErrorThreshold The maximal square pixel error, with range (0, infinity)
720 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
721 * @param maxValidCandidates Maximal number of candidates found already, this parameter will be used by all threads concurrently
722 * @param minSquareErrors Minimal square errors of candidates found already, this parameter will be used by all threads concurrently
723 * @param lock The lock object to avoid race conditions for the global parameter, should be nullptr in a single threaded call, must be defined in a multi threaded call
724 * @param firstIteration First iteration to be applied
725 * @param numberIterations Number of iterations to be applied
726 */
727 static void geometricTransformSubset(const GeometricTransformFunction geometricTransformFunction, const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator* randomGenerator, SquareMatrix3* transformMatrix, const unsigned int testCandidates, const Scalar squarePixelErrorThreshold, Indices32* usedIndices, unsigned int* maxValidCandidates, Scalar* minSquareErrors, Lock* lock, const unsigned int firstIteration, const unsigned int numberIterations);
728
729 /**
730 * Internal function to calculate the geometry transformation between two images transforming the projected planar object points between the two images.
731 * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = M * leftPoint).
732 * @param geometricTransformFunction The pointer to the geometric transformation function to be applied, must be valid
733 * @param leftImagePoints Image points in the left camera, must be valid
734 * @param numberLeftImagePoints The number of given left image points, with range [1, infinity)
735 * @param rightImagePoints Image points in the right camera, must be valid
736 * @param numberRightImagePoints The number of given right image points, with range [1, infinity)
737 * @param correspondences The pairs defining the non-bijective correspondences, with range [0, numberLeftImagePoints - 1]x[0, numberRightImagePoints - 1], must be valid
738 * @param numberCorrespondences The number of given correspondence pairs, with range [1, infinity)
739 * @param randomGenerator Random generator object to be used for creating random numbers
740 * @param transformMatrix Resulting homography for the given image points
741 * @param testCandidates Number of candidates used in each RANSAC iterations, with range [1, correspondences]
742 * @param squarePixelErrorThreshold The maximal square pixel error, with range (0, infinity)
743 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
744 * @param maxValidCandidates Maximal number of candidates found already, this parameter will be used by all threads concurrently
745 * @param minSquareErrors Minimal square errors of candidates found already, this parameter will be used by all threads concurrently
746 * @param lock The lock object to avoid race conditions for the global parameter, should be nullptr in a single threaded call, must be defined in a multi threaded call
747 * @param firstIteration First iteration to be applied
748 * @param numberIterations Number of iterations to be applied
749 */
750 static void geometricTransformForNonBijectiveCorrespondencesSubset(const GeometricTransformFunction geometricTransformFunction, const Vector2* leftImagePoints, const size_t numberLeftImagePoints, const Vector2* rightImagePoints, const size_t numberRightImagePoints, const IndexPair32* correspondences, const size_t numberCorrespondences, RandomGenerator* randomGenerator, SquareMatrix3* transformMatrix, const unsigned int testCandidates, const Scalar squarePixelErrorThreshold, Indices32* usedIndices, unsigned int* maxValidCandidates, Scalar* minSquareErrors, Lock* lock, const unsigned int firstIteration, const unsigned int numberIterations);
751
752 /**
753 * Internal function to calculate inverted flipped camera poses (up to a common 3d projection transformation) for image point corresponds between images from multiple views.
754 * @param imagePointsPerPose Image points per view (at least 3 views and at least 6 point correspondences)
755 * @param views Count of views
756 * @param randomGenerator Random generator object to be used for creating random numbers
757 * @param posesIF Resulting camera projection matrices per view (inverted flipped)
758 * @param squarePixelErrorThreshold Maximal square pixel error of a valid projection of a 3D point onto the 2D image plane, with range (0, infinity)
759 * @param objectPointsIF Optional vector which will receive the object points of the image point correspondences, if defined
760 * @param usedIndices Optional vector which will receive the indices of the used image correspondences, if defined
761 * @param minSquareErrors Minimal square errors of candidates found already, this parameter will be used by all threads concurrently
762 * @param lock The lock object to avoid race conditions for the global parameter, should be nullptr in a single threaded call, must be defined in a multi threaded call
763 * @param firstIteration First iteration to be applied
764 * @param numberIterations Number of iterations to be applied
765 * @see Geometry::MultipleViewGeometry::projectiveReconstructionFrom6PointsIF().
766 */
767 static void projectiveReconstructionFrom6PointsIFSubset(const ConstIndexedAccessor<Vectors2>* imagePointsPerPose, const size_t views, RandomGenerator* randomGenerator, NonconstIndexedAccessor<HomogenousMatrix4>* posesIF, const Scalar squarePixelErrorThreshold, NonconstArrayAccessor<Vector3>* objectPointsIF, Indices32* usedIndices, Scalar* minSquareErrors, Lock* lock, const unsigned int firstIteration, const unsigned int numberIterations);
768
769 /**
770 * Selects random indices from a given vector of indices.
771 * The selected indicies will be placed at the beginning of the vector.<br>
772 * The index vector does not loose any index, and can be reused.
773 * @param indices The vector of indices from which random indices will be selected, the selected indices will be placed at the beginning of the vector
774 * @param subset The number of random indices to be selected, with range [1, indices.size()]
775 * @param randomGenerator The random generator to be used
776 */
777 static void subsetIndices(Indices32& indices, const size_t subset, RandomGenerator& randomGenerator);
778};
779
780inline bool RANSAC::homographyMatrix(const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator& randomGenerator, SquareMatrix3& homography, const unsigned int testCandidates, const bool refine, const unsigned int iterations, const Scalar squarePixelErrorThreshold, Indices32* usedIndices, Worker* worker, const bool useSVD)
781{
782 ocean_assert(leftImagePoints != nullptr && rightImagePoints != nullptr);
783 ocean_assert(correspondences >= 4);
784 ocean_assert(testCandidates >= 4u);
785 ocean_assert(squarePixelErrorThreshold > 0);
786
787 if (refine)
788 {
789 if (useSVD)
790 {
791 return homographyMatrix<true, true>(leftImagePoints, rightImagePoints, correspondences, randomGenerator, homography, testCandidates, iterations, squarePixelErrorThreshold, usedIndices, worker);
792 }
793 else
794 {
795 return homographyMatrix<true, false>(leftImagePoints, rightImagePoints, correspondences, randomGenerator, homography, testCandidates, iterations, squarePixelErrorThreshold, usedIndices, worker);
796 }
797 }
798 else
799 {
800 if (useSVD)
801 {
802 return homographyMatrix<false, true>(leftImagePoints, rightImagePoints, correspondences, randomGenerator, homography, testCandidates, iterations, squarePixelErrorThreshold, usedIndices, worker);
803 }
804 else
805 {
806 return homographyMatrix<false, false>(leftImagePoints, rightImagePoints, correspondences, randomGenerator, homography, testCandidates, iterations, squarePixelErrorThreshold, usedIndices, worker);
807 }
808 }
809}
810
811inline bool RANSAC::homographyMatrixForNonBijectiveCorrespondences(const Vector2* leftImagePoints, const size_t numberLeftImagePoints, const Vector2* rightImagePoints, const size_t numberRightImagePoints, const IndexPair32* correspondences, const size_t numberCorrespondences, RandomGenerator& randomGenerator, SquareMatrix3& right_H_left, const unsigned int testCandidates, const bool refine, const unsigned int iterations, const Scalar squarePixelErrorThreshold, Indices32* usedIndices, Worker* worker, const bool useSVD)
812{
813 ocean_assert(leftImagePoints != nullptr && rightImagePoints != nullptr);
814 ocean_assert(numberLeftImagePoints >= 4 && numberRightImagePoints >= 4);
815 ocean_assert(correspondences != nullptr);
816 ocean_assert(numberCorrespondences >= 4);
817 ocean_assert(testCandidates >= 4u);
818 ocean_assert(squarePixelErrorThreshold > 0);
819
820 if (refine)
821 {
822 if (useSVD)
823 {
824 return homographyMatrixForNonBijectiveCorrespondences<true, true>(leftImagePoints, numberLeftImagePoints, rightImagePoints, numberRightImagePoints, correspondences, numberCorrespondences, randomGenerator, right_H_left, testCandidates, iterations, squarePixelErrorThreshold, usedIndices, worker);
825 }
826 else
827 {
828 return homographyMatrixForNonBijectiveCorrespondences<true, false>(leftImagePoints, numberLeftImagePoints, rightImagePoints, numberRightImagePoints, correspondences, numberCorrespondences, randomGenerator, right_H_left, testCandidates, iterations, squarePixelErrorThreshold, usedIndices, worker);
829 }
830 }
831 else
832 {
833 if (useSVD)
834 {
835 return homographyMatrixForNonBijectiveCorrespondences<false, true>(leftImagePoints, numberLeftImagePoints, rightImagePoints, numberRightImagePoints, correspondences, numberCorrespondences, randomGenerator, right_H_left, testCandidates, iterations, squarePixelErrorThreshold, usedIndices, worker);
836 }
837 else
838 {
839 return homographyMatrixForNonBijectiveCorrespondences<false, false>(leftImagePoints, numberLeftImagePoints, rightImagePoints, numberRightImagePoints, correspondences, numberCorrespondences, randomGenerator, right_H_left, testCandidates, iterations, squarePixelErrorThreshold, usedIndices, worker);
840 }
841 }
842}
843
844template <bool tRefine, bool tUseSVD>
845bool RANSAC::homographyMatrix(const Vector2* leftImagePoints, const Vector2* rightImagePoints, const size_t correspondences, RandomGenerator& randomGenerator, SquareMatrix3& homography, const unsigned int testCandidates, const unsigned int iterations, const Scalar squarePixelErrorThreshold, Indices32* usedIndices, Worker* worker)
846{
847 ocean_assert(leftImagePoints != nullptr && rightImagePoints != nullptr);
848 ocean_assert(correspondences >= 4);
849 ocean_assert(testCandidates >= 4u);
850 ocean_assert(squarePixelErrorThreshold > 0);
851
852 if (testCandidates < 4u || correspondences < testCandidates)
853 {
854 return false;
855 }
856
857 Indices32 tmpIndices;
858 Indices32* indices = (tRefine || usedIndices) ? &tmpIndices : nullptr;
859
860 unsigned int maxValidCorrespondences = testCandidates - 1u;
861 Scalar minSquareErrors = Numeric::maxValue();
862
863 if (worker != nullptr)
864 {
865 Lock lock;
866
867 if constexpr (tUseSVD)
868 {
869 worker->executeFunction(Worker::Function::createStatic(&geometricTransformSubset, Homography::homographyMatrixSVD, leftImagePoints, rightImagePoints, correspondences, &randomGenerator, &homography, testCandidates, squarePixelErrorThreshold, indices, &maxValidCorrespondences, &minSquareErrors, (Lock*)(&lock), 0u, 0u), 0u, iterations, 12u, 13u, 5u);
870 }
871 else
872 {
873 worker->executeFunction(Worker::Function::createStatic(&geometricTransformSubset, Homography::homographyMatrixLinearWithoutOptimations, leftImagePoints, rightImagePoints, correspondences, &randomGenerator, &homography, testCandidates, squarePixelErrorThreshold, indices, &maxValidCorrespondences, &minSquareErrors, (Lock*)(&lock), 0u, 0u), 0u, iterations, 12u, 13u, 5u);
874 }
875 }
876 else
877 {
878 if constexpr (tUseSVD)
879 {
880 geometricTransformSubset(Homography::homographyMatrixSVD, leftImagePoints, rightImagePoints, correspondences, &randomGenerator, &homography, testCandidates, squarePixelErrorThreshold, indices, &maxValidCorrespondences, &minSquareErrors, nullptr, 0u, iterations);
881 }
882 else
883 {
884 geometricTransformSubset(Homography::homographyMatrixLinearWithoutOptimations, leftImagePoints, rightImagePoints, correspondences, &randomGenerator, &homography, testCandidates, squarePixelErrorThreshold, indices, &maxValidCorrespondences, &minSquareErrors, nullptr, 0u, iterations);
885 }
886 }
887
888 if (maxValidCorrespondences < testCandidates || homography.isSingular())
889 {
890 return false;
891 }
892
894
895 if constexpr (tRefine)
896 {
897 ocean_assert(indices);
898
899 const Vectors2 validLeftImagePoints(Subset::subset(leftImagePoints, correspondences, *indices));
900 const Vectors2 validRightImagePoints(Subset::subset(rightImagePoints, correspondences, *indices));
901
902 SquareMatrix3 optimizedHomography;
903 if (Geometry::NonLinearOptimizationHomography::optimizeHomography<Geometry::Estimator::ET_SQUARE>(homography, validLeftImagePoints.data(), validRightImagePoints.data(), validLeftImagePoints.size(), 9u, optimizedHomography, 20u))
904 {
905 homography = optimizedHomography;
906
907 if (usedIndices)
908 {
909 indices->clear();
910
911 for (size_t n = 0; n < correspondences; ++n)
912 {
913 if (rightImagePoints[n].sqrDistance(homography * leftImagePoints[n]) <= squarePixelErrorThreshold)
914 {
915 indices->emplace_back(Index32(n));
916 }
917 }
918 }
919 }
920 }
921
922 if (usedIndices != nullptr)
923 {
924 *usedIndices = std::move(tmpIndices);
925 }
926
927 return true;
928}
929
930template <bool tRefine, bool tUseSVD>
931bool RANSAC::homographyMatrixForNonBijectiveCorrespondences(const Vector2* leftImagePoints, const size_t numberLeftImagePoints, const Vector2* rightImagePoints, const size_t numberRightImagePoints, const IndexPair32* correspondences, const size_t numberCorrespondences, RandomGenerator& randomGenerator, SquareMatrix3& right_H_left, const unsigned int testCandidates, const unsigned int iterations, const Scalar squarePixelErrorThreshold, Indices32* usedIndices, Worker* worker)
932{
933 ocean_assert(squarePixelErrorThreshold > 0);
934 ocean_assert(leftImagePoints && rightImagePoints);
935 ocean_assert(correspondences != nullptr);
936 ocean_assert(numberCorrespondences >= 4);
937
938 if (testCandidates < 4u || numberCorrespondences < testCandidates)
939 {
940 return false;
941 }
942
943 Indices32 tmpIndices;
944 Indices32* indices = (tRefine || usedIndices) ? &tmpIndices : nullptr;
945
946 unsigned int maxValidCorrespondences = testCandidates - 1u;
947 Scalar minSquareErrors = Numeric::maxValue();
948
949 if (worker != nullptr)
950 {
951 Lock lock;
952
953 if constexpr (tUseSVD)
954 {
955 worker->executeFunction(Worker::Function::createStatic(&geometricTransformForNonBijectiveCorrespondencesSubset, Homography::homographyMatrixSVD, leftImagePoints, numberLeftImagePoints, rightImagePoints, numberRightImagePoints, correspondences, numberCorrespondences, &randomGenerator, &right_H_left, testCandidates, squarePixelErrorThreshold, indices, &maxValidCorrespondences, &minSquareErrors, (Lock*)&lock, 0u, 0u), 0u, iterations, 15u, 16u, 5u);
956 }
957 else
958 {
959 worker->executeFunction(Worker::Function::createStatic(&geometricTransformForNonBijectiveCorrespondencesSubset, Homography::homographyMatrixLinearWithoutOptimations, leftImagePoints, numberLeftImagePoints, rightImagePoints, numberRightImagePoints, correspondences, numberCorrespondences, &randomGenerator, &right_H_left, testCandidates, squarePixelErrorThreshold, indices, &maxValidCorrespondences, &minSquareErrors, (Lock*)&lock, 0u, 0u), 0u, iterations, 15u, 16u, 5u);
960 }
961 }
962 else
963 {
964 if constexpr (tUseSVD)
965 {
966 geometricTransformForNonBijectiveCorrespondencesSubset(Homography::homographyMatrixSVD, leftImagePoints, numberLeftImagePoints, rightImagePoints, numberRightImagePoints, correspondences, numberCorrespondences, &randomGenerator, &right_H_left, testCandidates, squarePixelErrorThreshold, indices, &maxValidCorrespondences, &minSquareErrors, nullptr, 0u, iterations);
967 }
968 else
969 {
970 geometricTransformForNonBijectiveCorrespondencesSubset(Homography::homographyMatrixLinearWithoutOptimations, leftImagePoints, numberLeftImagePoints, rightImagePoints, numberRightImagePoints, correspondences, numberCorrespondences, &randomGenerator, &right_H_left, testCandidates, squarePixelErrorThreshold, indices, &maxValidCorrespondences, &minSquareErrors, nullptr, 0u, iterations);
971 }
972 }
973
974 if (maxValidCorrespondences < testCandidates || right_H_left.isSingular())
975 {
976 return false;
977 }
978
980
981 if constexpr (tRefine)
982 {
983 ocean_assert(indices);
984
985 Vectors2 validLeftImagePoints;
986 Vectors2 validRightImagePoints;
987
988 validLeftImagePoints.reserve(indices->size());
989 validRightImagePoints.reserve(indices->size());
990
991 for (const Index32& index : *indices)
992 {
993 const IndexPair32& correspondencePair = correspondences[index];
994
995 const unsigned int leftIndex = correspondencePair.first;
996 const unsigned int rightIndex = correspondencePair.second;
997
998 validLeftImagePoints.push_back(leftImagePoints[leftIndex]);
999 validRightImagePoints.push_back(rightImagePoints[rightIndex]);
1000 }
1001
1002 SquareMatrix3 optimizedHomography;
1003 if (Geometry::NonLinearOptimizationHomography::optimizeHomography<Geometry::Estimator::ET_SQUARE>(right_H_left, validLeftImagePoints.data(), validRightImagePoints.data(), validLeftImagePoints.size(), 9u, optimizedHomography, 20u))
1004 {
1005 right_H_left = optimizedHomography;
1006
1007 if (usedIndices)
1008 {
1009 indices->clear();
1010
1011 for (size_t n = 0; n < numberCorrespondences; ++n)
1012 {
1013 const IndexPair32& correspondencePair = correspondences[n];
1014
1015 const unsigned int leftIndex = correspondencePair.first;
1016 const unsigned int rightIndex = correspondencePair.second;
1017
1018 if (rightImagePoints[rightIndex].sqrDistance(right_H_left * leftImagePoints[leftIndex]) <= squarePixelErrorThreshold)
1019 {
1020 indices->push_back((unsigned int)n);
1021 }
1022 }
1023 }
1024 }
1025 }
1026
1027 if (usedIndices != nullptr)
1028 {
1029 *usedIndices = std::move(tmpIndices);
1030 }
1031
1032 return true;
1033}
1034
1035inline bool RANSAC::p3p(const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, const unsigned int minimalValidCorrespondences, const bool refine, const unsigned int iterations, const Scalar sqrPixelErrorThreshold, Indices32* usedIndices, Scalar* sqrAccuracy, const Scalar* weights)
1036{
1037 const AnyCameraPinhole anyCameraPinhole(PinholeCamera(pinholeCamera, useDistortionParameters));
1038
1039 return p3p(nullptr, anyCameraPinhole, objectPointAccessor, imagePointAccessor, randomGenerator, pose, nullptr, nullptr, minimalValidCorrespondences, refine, iterations, sqrPixelErrorThreshold, usedIndices, sqrAccuracy, weights);
1040}
1041
1042inline bool RANSAC::p3p(const HomogenousMatrix4& world_T_roughCamera, const AnyCamera& camera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, HomogenousMatrix4& world_T_camera, const Vector3& maxPositionOffset, const Scalar maxOrientationOffset, const unsigned int minValidCorrespondences, const bool refine, const unsigned int iterations, const Scalar sqrPixelErrorThreshold, Indices32* usedIndices, Scalar* sqrAccuracy, const Scalar* weights)
1043{
1044 return p3p(&world_T_roughCamera, camera, objectPointAccessor, imagePointAccessor, randomGenerator, world_T_camera, &maxPositionOffset, &maxOrientationOffset, minValidCorrespondences, refine, iterations, sqrPixelErrorThreshold, usedIndices, sqrAccuracy, weights);
1045}
1046
1047inline bool RANSAC::p3p(const HomogenousMatrix4& initialPose, const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, const Vector3& maxPositionOffset, const Scalar maxOrientationOffset, const unsigned int minValidCorrespondences, const bool refine, const unsigned int iterations, const Scalar sqrPixelErrorThreshold, Indices32* usedIndices, Scalar* sqrAccuracy, const Scalar* weights)
1048{
1049 const AnyCameraPinhole anyCameraPinhole(PinholeCamera(pinholeCamera, useDistortionParameters));
1050
1051 return p3p(&initialPose, anyCameraPinhole, objectPointAccessor, imagePointAccessor, randomGenerator, pose, &maxPositionOffset, &maxOrientationOffset, minValidCorrespondences, refine, iterations, sqrPixelErrorThreshold, usedIndices, sqrAccuracy, weights);
1052}
1053
1054inline bool RANSAC::p3pZoom(const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, Scalar& zoom, const unsigned int minimalValidCorrespondences, const bool refine, const unsigned int iterations, const Scalar sqrPixelErrorThreshold, Indices32* usedIndices, Scalar* sqrAccuracy, const Scalar* weights)
1055{
1056 return p3pZoom(nullptr, nullptr, pinholeCamera, objectPointAccessor, imagePointAccessor, randomGenerator, useDistortionParameters, pose, zoom, nullptr, nullptr, minimalValidCorrespondences, refine, iterations, sqrPixelErrorThreshold, usedIndices, sqrAccuracy, weights);
1057}
1058
1059inline bool RANSAC::p3pZoom(const HomogenousMatrix4& initialPose, const Scalar initialZoom, const PinholeCamera& pinholeCamera, const ConstIndexedAccessor<Vector3>& objectPointAccessor, const ConstIndexedAccessor<Vector2>& imagePointAccessor, RandomGenerator& randomGenerator, const bool useDistortionParameters, HomogenousMatrix4& pose, Scalar& zoom, const Vector3& maxPositionOffset, const Scalar maxOrientationOffset, const unsigned int minValidCorrespondences, const bool refine, const unsigned int iterations, const Scalar sqrPixelErrorThreshold, Indices32* usedIndices, Scalar* sqrAccuracy, const Scalar* weights)
1060{
1061 ocean_assert(initialZoom > Numeric::eps());
1062 return p3pZoom(&initialPose, &initialZoom, pinholeCamera, objectPointAccessor, imagePointAccessor, randomGenerator, useDistortionParameters, pose, zoom, &maxPositionOffset, &maxOrientationOffset, minValidCorrespondences, refine, iterations, sqrPixelErrorThreshold, usedIndices, sqrAccuracy, weights);
1063}
1064
1065inline bool RANSAC::objectPoint(const AnyCamera& camera, const ConstIndexedAccessor<HomogenousMatrix4>& world_T_cameras, const ConstIndexedAccessor<Vector2>& imagePoints, RandomGenerator& randomGenerator, Vector3& objectPoint, const unsigned int iterations, const Scalar maximalSqrError, const unsigned int minValidCorrespondences, const bool onlyFrontObjectPoint, const Estimator::EstimatorType refinementEstimator, Scalar* finalRobustError, Indices32* usedIndices)
1066{
1067#if 1
1068 // creating local pointer to avoid Clang compiler bug
1069 const AnyCamera* cameraPointer = &camera;
1070 const ConstElementAccessor<const AnyCamera*> cameraAccessor(world_T_cameras.size(), cameraPointer);
1071#else
1072 const ConstElementAccessor<const AnyCamera*> cameraAccessor(world_T_cameras.size(), &camera);
1073#endif
1074
1075 return RANSAC::objectPoint(cameraAccessor, world_T_cameras, imagePoints, randomGenerator, objectPoint, iterations, maximalSqrError, minValidCorrespondences, onlyFrontObjectPoint, refinementEstimator, finalRobustError, usedIndices);
1076}
1077
1078}
1079
1080}
1081
1082#endif // META_OCEAN_GEOMETRY_RANSAC_H
virtual size_t size() const =0
Returns the number of accessible elements of this accessor object.
This class implements the abstract base class for all AnyCamera objects.
Definition AnyCamera.h:130
This class implements a specialized AnyCamera object wrapping the actual camera model.
Definition AnyCamera.h:608
static Caller< void > createStatic(typename StaticFunctionPointerMaker< 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 static function with no function parameter.
Definition Caller.h:2877
This class implements an accessor providing direct access to a constant array of elements while all e...
Definition Accessor.h:942
This class implements a base class for all indexed-based accessors allowing a constant reference acce...
Definition Accessor.h:241
std::vector< Pattern > Patterns
Definition of a vector holding calibration patterns.
Definition CameraCalibration.h:136
EstimatorType
Definition of individual robust estimator types.
Definition Estimator.h:34
This class implements a container allowing to define gravity constraints during e....
Definition GravityConstraints.h:63
static void normalizeHomography(SquareMatrixT3< T > &homography)
Normalizes a given homography forcing a 1 in the lower right matrix corner.
Definition Homography.h:466
static bool homographyMatrixSVD(const Vector2 *leftPoints, const Vector2 *rightPoints, const size_t correspondences, SquareMatrix3 &right_H_left)
Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear,...
static bool homographyMatrixLinearWithoutOptimations(const Vector2 *leftPoints, const Vector2 *rightPoints, const size_t correspondences, SquareMatrix3 &right_H_left)
Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear,...
This class implements several RANSAC functions for pose determination.
Definition RANSAC.h:41
static bool geometricTransformForNonBijectiveCorrespondences(const GeometricTransformFunction geometricTransformFunction, const Vector2 *leftImagePoints, const size_t numberLeftImagePoints, const Vector2 *rightImagePoints, const size_t numberRightImagePoints, const IndexPair32 *correspondences, const size_t numberCorrespondences, RandomGenerator &randomGenerator, SquareMatrix3 &transformMatrix, const unsigned int testCandidates, const unsigned int iterations, const Scalar squarePixelErrorThreshold, Indices32 *usedIndices, Worker *worker)
Calculates the geometry transformation between two images transforming the given image points between...
static void geometricTransformSubset(const GeometricTransformFunction geometricTransformFunction, const Vector2 *leftImagePoints, const Vector2 *rightImagePoints, const size_t correspondences, RandomGenerator *randomGenerator, SquareMatrix3 *transformMatrix, const unsigned int testCandidates, const Scalar squarePixelErrorThreshold, Indices32 *usedIndices, unsigned int *maxValidCandidates, Scalar *minSquareErrors, Lock *lock, const unsigned int firstIteration, const unsigned int numberIterations)
Internal function to calculate the geometry transformation between two images transforming the projec...
static void subsetIndices(Indices32 &indices, const size_t subset, RandomGenerator &randomGenerator)
Selects random indices from a given vector of indices.
static bool p3p(const AnyCamera &anyCamera, const ConstIndexedAccessor< Vector3 > &objectPointAccessor, const ConstIndexedAccessor< Vector2 > &imagePointAccessor, RandomGenerator &randomGenerator, HomogenousMatrix4 &world_T_camera, const unsigned int minimalValidCorrespondences=5u, const bool refine=true, const unsigned int iterations=20u, const Scalar sqrPixelErrorThreshold=Scalar(5 *5), Indices32 *usedIndices=nullptr, Scalar *sqrAccuracy=nullptr, const GravityConstraints *gravityConstraints=nullptr)
Calculates a pose using the perspective pose problem with three point correspondences using any camer...
static bool extrinsicMatrix(const PinholeCamera &leftCamera, const PinholeCamera &rightCamera, const Vector2 *leftImagePoints, const Vector2 *rightImagePoints, const size_t correspondences, HomogenousMatrix4 &transformation, const unsigned int testCandidates=8u, const unsigned int iterations=20u, const Scalar squarePixelErrorThreshold=Scalar(9), const Box3 &maxTranslation=Box3(), const Scalar maxRotation=Numeric::pi(), Indices32 *usedIndices=nullptr)
Calculates the extrinsic camera matrix by given point correspondences for two stereo images.
static bool translation(const ConstIndexedAccessor< Vector2 > &translations, RandomGenerator &randomGenerator, Vector2 &translation, const bool refine=true, const unsigned int iterations=20u, const Scalar maxSqrError=Scalar(5 *5), Scalar *finalError=nullptr, Indices32 *usedIndices=nullptr)
Determines the 2D translation (offset/translation vector) from a set of given 2D vectors.
bool(*)(const Vector2 *, const Vector2 *, const size_t, SquareMatrix3 &) GeometricTransformFunction
Definition of a function pointer determining a geometric transformation e.g., a affine transformation...
Definition RANSAC.h:52
static bool objectPoint(const AnyCamera &camera, const ConstIndexedAccessor< HomogenousMatrix4 > &world_T_cameras, const ConstIndexedAccessor< Vector2 > &imagePoints, RandomGenerator &randomGenerator, Vector3 &objectPoint, const unsigned int iterations=20u, const Scalar maximalSqrError=Scalar(3 *3), const unsigned int minValidCorrespondences=2u, const bool onlyFrontObjectPoint=true, const Estimator::EstimatorType refinementEstimator=Estimator::ET_SQUARE, Scalar *finalRobustError=nullptr, Indices32 *usedIndices=nullptr)
Determines the 3D object point for a set of image points observing the same object point under indivi...
Definition RANSAC.h:1065
static bool p3pZoom(const HomogenousMatrix4 *initialPose, const Scalar *initialZoom, const PinholeCamera &pinholeCamera, const ConstIndexedAccessor< Vector3 > &objectPointAccessor, const ConstIndexedAccessor< Vector2 > &imagePointAccessor, RandomGenerator &randomGenerator, const bool useDistortionParameters, HomogenousMatrix4 &pose, Scalar &zoom, const Vector3 *maxPositionOffset, const Scalar *maxOrientationOffset, const unsigned int minValidCorrespondences=5u, const bool refine=true, const unsigned int iterations=20u, const Scalar sqrPixelErrorThreshold=Scalar(5 *5), Indices32 *usedIndices=nullptr, Scalar *sqrAccuracy=nullptr, const Scalar *weights=nullptr)
Calculates a pose including zoom factor using the perspective pose problem with three point correspon...
static unsigned int iterations(const unsigned int model, const Scalar successProbability=Scalar(0.99), const Scalar faultyRate=Scalar(0.2), const unsigned int maximalIterations=1000000u)
Calculates the number of iterations necessary to find an outlier-free model data set.
static bool orientation(const AnyCamera &camera, const ConstIndexedAccessor< Vector3 > &objectPoints, const ConstIndexedAccessor< Vector2 > &imagePoints, RandomGenerator &randomGenerator, Quaternion &world_R_camera, const unsigned int minValidCorrespondences=5u, const unsigned int iterations=20u, const Scalar maxSqrError=Scalar(5 *5), Scalar *finalError=nullptr, Indices32 *usedIndices=nullptr, const GravityConstraints *gravityConstraints=nullptr)
Determines the 3DOF rotation of a camera pose for a set of given 2D/3D point correspondences by minim...
static bool objectTransformationStereo(const AnyCamera &anyCameraA, const AnyCamera &anyCameraB, const HomogenousMatrix4 &world_T_cameraA, const HomogenousMatrix4 &world_T_cameraB, const ConstIndexedAccessor< Vector3 > &objectPointsA, const ConstIndexedAccessor< Vector3 > &objectPointsB, const ConstIndexedAccessor< Vector2 > &imagePointsA, const ConstIndexedAccessor< Vector2 > &imagePointsB, RandomGenerator &randomGenerator, HomogenousMatrix4 &world_T_object, const unsigned int minimalValidCorrespondences=5u, const bool refine=true, const unsigned int iterations=20u, const Scalar sqrPixelErrorThreshold=Scalar(5 *5), Indices32 *usedIndicesA=nullptr, Indices32 *usedIndicesB=nullptr, Scalar *sqrAccuracy=nullptr, const bool allowMonoObservation=true)
Determines the 6-DOF object transformation between world and object so that the transformation fits w...
static bool determineCameraCalibrationPlanar(const unsigned int width, const unsigned int height, const CameraCalibration::Patterns &calibrationPatterns, const Vector2 &calibrationPatternBoxSize, const unsigned int testCandidates, PinholeCamera &pinholeCamera, const unsigned int iterations=20u, Scalar *sqrAccuracy=nullptr, Worker *worker=nullptr, Indices32 *usedIndices=nullptr)
Determines the camera calibration for several given camera calibration patterns, each pattern object ...
static void projectiveReconstructionFrom6PointsIFSubset(const ConstIndexedAccessor< Vectors2 > *imagePointsPerPose, const size_t views, RandomGenerator *randomGenerator, NonconstIndexedAccessor< HomogenousMatrix4 > *posesIF, const Scalar squarePixelErrorThreshold, NonconstArrayAccessor< Vector3 > *objectPointsIF, Indices32 *usedIndices, Scalar *minSquareErrors, Lock *lock, const unsigned int firstIteration, const unsigned int numberIterations)
Internal function to calculate inverted flipped camera poses (up to a common 3d projection transforma...
static bool plane(const ConstIndexedAccessor< Vector3 > &objectPoints, RandomGenerator &randomGenerator, Plane3 &plane, const unsigned int iterations=20u, const Scalar medianDistanceFactor=Scalar(0.1), const unsigned int minValidCorrespondences=3u, const Estimator::EstimatorType refinementEstimator=Estimator::ET_SQUARE, Scalar *finalError=nullptr, Indices32 *usedIndices=nullptr)
Determines a 3D plane best matching to a set of given 3D object points.
static bool affineMatrix(const Vector2 *leftImagePoints, const Vector2 *rightImagePoints, const size_t correspondences, RandomGenerator &randomGenerator, SquareMatrix3 &right_A_left, const unsigned int testCandidates=6u, const unsigned int iterations=20u, const Scalar squarePixelErrorThreshold=Scalar(3 *3), Indices32 *usedIndices=nullptr, Worker *worker=nullptr)
Calculates the affine transformation (6DOF - translation, rotation, scale, aspect ratio,...
static bool objectPoint(const AnyCamera &camera, const ConstIndexedAccessor< SquareMatrix3 > &world_R_cameras, const ConstIndexedAccessor< Vector2 > &imagePoints, RandomGenerator &randomGenerator, Vector3 &objectPoint, const Scalar objectPointDistance, const unsigned int iterations=20u, const Scalar maximalError=Scalar(3 *3), const unsigned int minValidCorrespondences=2u, const bool onlyFrontObjectPoint=true, const Estimator::EstimatorType refinementEstimator=Estimator::ET_SQUARE, Scalar *finalError=nullptr, Indices32 *usedIndices=nullptr)
Determines the 3D object point for a set of image points observing the same object point under indivi...
static bool similarityMatrix(const Vector2 *leftImagePoints, const Vector2 *rightImagePoints, const size_t correspondences, RandomGenerator &randomGenerator, SquareMatrix3 &similarity, const unsigned int testCandidates=4u, const unsigned int iterations=20u, const Scalar squarePixelErrorThreshold=Scalar(9), Indices32 *usedIndices=nullptr, Worker *worker=nullptr)
Calculates the similarity transformation (4DOF - translation, rotation, scale) between two images tra...
static bool projectiveReconstructionFrom6PointsIF(const ConstIndexedAccessor< Vectors2 > &imagePointsPerPose, NonconstIndexedAccessor< HomogenousMatrix4 > *posesIF, const unsigned int iterations=20u, const Scalar squarePixelErrorThreshold=Scalar(9), NonconstArrayAccessor< Vector3 > *objectPointsIF=nullptr, Indices32 *usedIndices=nullptr, Worker *worker=nullptr)
Calculates inverted flipped camera poses (up to a common 3d projection transformation) for image poin...
static bool homographyMatrix(const Vector2 *leftImagePoints, const Vector2 *rightImagePoints, const size_t correspondences, RandomGenerator &randomGenerator, SquareMatrix3 &homography, const unsigned int testCandidates=8u, const bool refine=true, const unsigned int iterations=20u, const Scalar squarePixelErrorThreshold=Scalar(9), Indices32 *usedIndices=nullptr, Worker *worker=nullptr, const bool useSVD=true)
Calculates the homography between two images transforming the given image points between two images.
Definition RANSAC.h:780
static bool line(const ConstIndexedAccessor< Vector2 > &positions, RandomGenerator &randomGenerator, Line2 &line, const bool refine=true, const unsigned int iterations=20u, const Scalar maxSqrError=Scalar(5 *5), Scalar *finalError=nullptr, Indices32 *usedIndices=nullptr)
Determines the 2D line best fitting to a set of given 2D positions.
static bool homographyMatrixForNonBijectiveCorrespondences(const Vector2 *leftImagePoints, const size_t numberLeftImagePoints, const Vector2 *rightImagePoints, const size_t numberRightImagePoints, const IndexPair32 *correspondences, const size_t numberCorrespondences, RandomGenerator &randomGenerator, SquareMatrix3 &right_H_left, const unsigned int testCandidates=8u, const bool refine=true, const unsigned int iterations=20u, const Scalar squarePixelErrorThreshold=Scalar(9), Indices32 *usedIndices=nullptr, Worker *worker=nullptr, const bool useSVD=true)
Calculates the homography between two images transforming the given image points between two images.
Definition RANSAC.h:811
static bool p3pZoom(const PinholeCamera &pinholeCamera, const ConstIndexedAccessor< Vector3 > &objectPointAccessor, const ConstIndexedAccessor< Vector2 > &imagePointAccessor, RandomGenerator &randomGenerator, const bool useDistortionParameters, HomogenousMatrix4 &pose, Scalar &zoom, const unsigned int minimalValidCorrespondences=5u, const bool refine=true, const unsigned int iterations=20u, const Scalar sqrPixelErrorThreshold=Scalar(5 *5), Indices32 *usedIndices=nullptr, Scalar *sqrAccuracy=nullptr, const Scalar *weights=nullptr)
Calculates a pose including zoom factor using the perspective pose problem with three point correspon...
Definition RANSAC.h:1054
static bool direction(const ConstIndexedAccessor< Vector2 > &directions, RandomGenerator &randomGenerator, Vector2 &direction, const bool acceptOppositeDirections, const bool refine=true, const unsigned int iterations=20u, const Scalar maxAngle=Numeric::deg2rad(5), Scalar *finalError=nullptr, Indices32 *usedIndices=nullptr)
Determines the 2D direction from a set of given 2D directions provided as unit vectors.
static void geometricTransformForNonBijectiveCorrespondencesSubset(const GeometricTransformFunction geometricTransformFunction, const Vector2 *leftImagePoints, const size_t numberLeftImagePoints, const Vector2 *rightImagePoints, const size_t numberRightImagePoints, const IndexPair32 *correspondences, const size_t numberCorrespondences, RandomGenerator *randomGenerator, SquareMatrix3 *transformMatrix, const unsigned int testCandidates, const Scalar squarePixelErrorThreshold, Indices32 *usedIndices, unsigned int *maxValidCandidates, Scalar *minSquareErrors, Lock *lock, const unsigned int firstIteration, const unsigned int numberIterations)
Internal function to calculate the geometry transformation between two images transforming the projec...
static bool plane(const Plane3 &initialPlane, const ConstIndexedAccessor< Vector3 > &objectPoints, RandomGenerator &randomGenerator, Plane3 &plane, const unsigned int iterations=20u, const Scalar maximalNormalOrientationOffset=Numeric::deg2rad(30), const Scalar medianDistanceFactor=Scalar(0.1), const unsigned int minValidCorrespondences=3u, const Estimator::EstimatorType refinementEstimator=Estimator::ET_SQUARE, Scalar *finalError=nullptr, Indices32 *usedIndices=nullptr)
Optimizes an already known 3D plane by minimizing the error between the plane and a set of given 3D o...
static bool geometricTransform(const GeometricTransformFunction geometricTransformFunction, const Vector2 *leftImagePoints, const Vector2 *rightImagePoints, const size_t correspondences, RandomGenerator &randomGenerator, SquareMatrix3 &transformMatrix, const unsigned int testCandidates, const unsigned int iterations, const Scalar squarePixelErrorThreshold, Indices32 *usedIndices, Worker *worker)
Calculates the geometry transformation between two images transforming the given image points between...
static bool homographyMatrices(const Vector2 *leftImagePoints, const Vector2 *rightImagePoints, const size_t correspondences, const Vector2 &leftQuadrantCenter, RandomGenerator &randomGenerator, SquareMatrix3 homographies[4], const unsigned int testCandidates=8u, const unsigned int iterations=20u, const Scalar squarePixelErrorThreshold=Scalar(9), Indices32 *usedIndices=nullptr, Worker *worker=nullptr)
Calculates four homographies between two images transforming the given image points between two image...
static bool fundamentalMatrix(const Vector2 *leftImagePoints, const Vector2 *rightImagePoints, const size_t correspondences, RandomGenerator &randomGenerator, SquareMatrix3 &right_F_left, const size_t testCandidates=8, const unsigned int iterations=20u, const Scalar maxScalarProduct=Scalar(0.001), Indices32 *usedIndices=nullptr)
Determines the fundamental matrix for given image point correspondences for two stereo images.
static void determineCameraCalibrationPlanarIteration(const unsigned int width, const unsigned int height, const ConstIndexedAccessor< Vectors3 > *objectPointGroups, const ConstIndexedAccessor< Vectors2 > *imagePointGroups, Indices32 *indices, PinholeCamera *pinholeCamera, Scalar *sqrAccuracy)
Performs execution of a camera calibration for a given subset of the entire data provided.
static bool p3p(const HomogenousMatrix4 *world_T_roughCamera, const AnyCamera &camera, const ConstIndexedAccessor< Vector3 > &objectPointAccessor, const ConstIndexedAccessor< Vector2 > &imagePointAccessor, RandomGenerator &randomGenerator, HomogenousMatrix4 &world_T_camera, const Vector3 *maxPositionOffset, const Scalar *maxOrientationOffset, const unsigned int minValidCorrespondences, const bool refine, const unsigned int iterations, const Scalar sqrPixelErrorThreshold, Indices32 *usedIndices, Scalar *sqrAccuracy, const Scalar *weights)
Calculates a camera pose using the perspective pose problem with three point correspondences.
static bool objectPoint(const ConstIndexedAccessor< const AnyCamera * > &cameras, const ConstIndexedAccessor< HomogenousMatrix4 > &world_T_cameras, const ConstIndexedAccessor< Vector2 > &imagePoints, RandomGenerator &randomGenerator, Vector3 &objectPoint, const unsigned int iterations=20u, const Scalar maximalSqrError=Scalar(3 *3), const unsigned int minValidCorrespondences=2u, const bool onlyFrontObjectPoint=true, const Estimator::EstimatorType refinementEstimator=Estimator::ET_SQUARE, Scalar *finalRobustError=nullptr, Indices32 *usedIndices=nullptr)
Determines the 3D object point for a set of image points observing the same object point under indivi...
This class implements an infinite line in 2D space.
Definition Line2.h:83
This class implements a recursive lock object.
Definition Lock.h:31
This class implements an accessor providing direct access to an array of elements.
Definition Accessor.h:707
This class implements a base class for all indexed-based accessors allowing a non-constant reference ...
Definition Accessor.h:284
static constexpr T eps()
Returns a small epsilon.
static constexpr T maxValue()
Returns the max scalar value.
Definition Numeric.h:3253
This class implements a generator for random numbers.
Definition RandomGenerator.h:42
const T * data() const
Returns a pointer to the internal values.
Definition SquareMatrix3.h:1047
bool isSingular() const
Returns whether this matrix is singular (and thus cannot be inverted).
Definition SquareMatrix3.h:1342
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:777
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.
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition base/Utilities.h:1159
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition Base.h:96
uint32_t Index32
Definition of a 32 bit index value.
Definition Base.h:84
std::pair< Index32, Index32 > IndexPair32
Definition of a pair holding 32 bit indices.
Definition Base.h:138
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
PinholeCameraT< Scalar > PinholeCamera
Definition of an pinhole camera object with Scalar precision.
Definition PinholeCamera.h:39
float Scalar
Definition of a scalar type.
Definition Math.h:129
The namespace covering the entire Ocean framework.
Definition Accessor.h:15