Ocean
Homography.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_HOMOGRAPHY_H
9 #define META_OCEAN_GEOMETRY_HOMOGRAPHY_H
10 
13 
14 #include "ocean/base/Accessor.h"
15 
16 #include "ocean/math/AnyCamera.h"
19 #include "ocean/math/Plane3.h"
21 
22 namespace Ocean
23 {
24 
25 namespace Geometry
26 {
27 
28 /**
29  * This class implements functions necessary for computations with homographies.
30  * @ingroup geometry
31  */
32 class OCEAN_GEOMETRY_EXPORT Homography
33 {
34  public:
35 
36  /**
37  * Calculates the homography between two images transforming the projected planar object points between the two images.
38  * The left camera is expected to be not rotated (the camera has the default viewing direction).<br>
39  * The default camera viewing direction is defined along the negative z-axis and has the y-axis as up vector.<br>
40  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).
41  * @param left_T_right The rotation between right camera and left camera, must be valid
42  * @param leftCamera The left camera profile, must be valid
43  * @param rightCamera The right camera profile, must be valid
44  * @return Resulting homography between left and right points (right_H_left)
45  */
46  static SquareMatrix3 homographyMatrix(const Quaternion& left_T_right, const AnyCamera& leftCamera, const AnyCamera& rightCamera);
47 
48  /**
49  * Deprecated.
50  *
51  * Calculates the homography between two images transforming the projected planar object points between the two images.
52  * The left camera is expected to be not rotated (the camera has the default viewing direction).<br>
53  * The default camera viewing direction is defined along the negative z-axis and has the y-axis as up vector.<br>
54  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).
55  * @param left_T_right The rotation between right camera and left camera, must be valid
56  * @param leftCamera The left camera profile, must be valid
57  * @param rightCamera The right camera profile, must be valid
58  * @return Resulting homography between left and right points (right_H_left)
59  */
60  static SquareMatrix3 homographyMatrix(const Quaternion& left_T_right, const PinholeCamera& leftCamera, const PinholeCamera& rightCamera);
61 
62  /**
63  * Calculates the homography between two images transforming the projected planar object points between the two images.
64  * The default camera viewing direction is defined along the negative z-axis and has the y-axis as up vector.<br>
65  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).
66  * @param world_R_left The rotation between left camera and world, must be valid
67  * @param world_R_right The rotation between right camera and world, must be valid
68  * @param leftCamera The left camera profile, must be valid
69  * @param rightCamera The right camera profile, must be valid
70  * @return Resulting homography between left and right points (right_H_left)
71  */
72  static SquareMatrix3 homographyMatrix(const Quaternion& world_R_left, const Quaternion& world_R_right, const PinholeCamera& leftCamera, const PinholeCamera& rightCamera);
73 
74  /**
75  * Calculates the homography between two images transforming the projected planar object points between the two images.
76  * The left camera is expected to be in the world origin (an identity camera pose).<br>
77  * Further, the given plane must be defined in relation to the world.
78  * @param world_T_rightCamera The camera pose of the right camera, with default camera pointing towards the negative z-space with y-axis upwards, must be valid
79  * @param leftCamera The camera profile defining the projection of the left camera, must be valid
80  * @param rightCamera The camera profile defining the projection of the right camera, must be valid
81  * @param plane The plane defined in world, must be valid
82  * @return The resulting homography transforming points in the left image to points in the right image (right_H_left)
83  */
84  static SquareMatrix3 homographyMatrix(const HomogenousMatrix4& world_T_rightCamera, const PinholeCamera& leftCamera, const PinholeCamera& rightCamera, const Plane3& plane);
85 
86  /**
87  * Calculates the homography between two images transforming the projected planar object points between the two images.
88  * The given plane must be defined in relation to the left camera coordinate system.<br>
89  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
90  * @param poseLeft The camera pose of the left camera in relation to a world coordinate system
91  * @param poseRight The camera pose of the right camera in relation to a world coordinate system
92  * @param leftCamera Left camera profile
93  * @param rightCamera Right camera profile
94  * @param plane The plane defined in the coordinate system of the left camera
95  * @return Resulting homography
96  */
97  static SquareMatrix3 homographyMatrix(const HomogenousMatrix4& poseLeft, const HomogenousMatrix4& poseRight, const PinholeCamera& leftCamera, const PinholeCamera& rightCamera, const Plane3& plane);
98 
99  /**
100  * Calculates the homography that transforms points defined in a (planar) pattern image to points defined in a camera frame in which the pattern is visible.
101  * Thus, the resulting homography can be used to rectify a specific image content of a given live camera frame.<br>
102  * The resolution and aspect ratio of the resulting rectified frame (defined by 'patternWidth' and 'patternHeight') can be arbitrary.<br>
103  * The 3D coordinates of the corners of the planar pattern must be known (in relation to the given camera pose).<br>
104  * The given 6DOF pose is a standard extrinsic camera matrix with default transformation looking into the negative z-space with y-axis as up-vector.<br>
105  * The resulting homography transforms image points defined in the pattern image to image points defined in the camera frame (cameraPoint = H * patternPoint).<br>
106  * Beware: The resulting transformation does not cover the possible distortion of the camera profile.
107  * @param pinholeCamera The profile of the pinhole camera defining the project, must be valid
108  * @param pose The pose of the camera frame in which the pattern is visible, defined in relation to the world coordinate system must be valid
109  * @param patternObjectPointTopLeft The 3D location of the upper left corner of the pattern, defined in the world coordinate system, must be located in front of the camera, must be different from all other corners
110  * @param patternObjectPointBottomLeft The 3D location of the bottom left corner of the pattern, defined in the world coordinate system, must be located in front of the camera, must be different from all other corners
111  * @param patternObjectPointTopRight The 3D location of the upper right corner of the pattern, defined in the world coordinate system, must be located in front of the camera, must be different from all other corners
112  * @param patternWidth The width of the pattern frame in pixel space (e.g., the width of a resulting frame that shows the rectified pattern), with range [1, infinity)
113  * @param patternHeight The height of the pattern frame in pixel space (e.g., the width of a resulting frame that shows the rectified pattern), with range [1, infinity)
114  * @return The resulting homography transforming pattern points to camera points (cameraPoint = H * patternPoint)
115  * @see CV::Advanced::FrameRectification.
116  */
117  static SquareMatrix3 homographyMatrix(const PinholeCamera& pinholeCamera, const HomogenousMatrix4& pose, const Vector3& patternObjectPointTopLeft, const Vector3& patternObjectPointBottomLeft, const Vector3& patternObjectPointTopRight, const unsigned int patternWidth, const unsigned int patternHeight);
118 
119  /**
120  * Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear, perspective) between two images transforming the projected planar object points between the two images.
121  * This function either uses a SVD for the determination of a two-step approach which is several times faster.<br>
122  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
123  * As this function applies the image points in pixel space, the intrinsic camera matrices of both frames are not necessary.
124  * @param leftPoints Image points in the left camera, each point corresponds to one point in the right image
125  * @param rightPoints Image points in the right camera
126  * @param correspondences Number of points correspondences, with range [4, infinity)
127  * @param right_H_left Resulting homography for the given point correspondences (rightPoint = right_H_left * leftPoint)
128  * @param useSVD True, to use the slower SVD approach (i.e., homographyMatrixSVD); False, to use the two-step approach (i.e., homographyMatrixLinearWithOptimizations)
129  * @return True, if succeeded
130  * @see homographyMatrixSVD(), homographyMatrixLinear(), affineMatrix(), similarityMatrix().
131  */
132  static inline bool homographyMatrix(const Vector2* leftPoints, const Vector2* rightPoints, const size_t correspondences, SquareMatrix3& right_H_left, const bool useSVD = true);
133 
134  /**
135  * Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear, perspective) between two images transforming the projected planar object points between the two images.
136  * This function uses a singular value decomposition for the determination of the homography.<br>
137  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
138  * As this function applies the image points in pixel space, the intrinsic camera matrices of both frames are not necessary.
139  * @param leftPoints Image points in the left camera, each point corresponds to one point in the right image
140  * @param rightPoints Image points in the right camera
141  * @param correspondences Number of provided point correspondences, with range [4, infinity)
142  * @param right_H_left Resulting homography for the given point correspondences (rightPoint = right_H_left * leftPoint)
143  * @return True, if succeeded
144  * @see homographyMatrixLinear(), affineMatrix(), similarityMatrix().
145  */
146  static bool homographyMatrixSVD(const Vector2* leftPoints, const Vector2* rightPoints, const size_t correspondences, SquareMatrix3& right_H_left);
147 
148  /**
149  * Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear, perspective) between two images transforming the projected planar object points and lines between the two images.
150  * This function uses a singular value decomposition for the determination of the homography.<br>
151  * The resulting homography transforms image points defined in the left image to image points defined in the right image, and lines defined in the left image to lines defined in the right image, (rightPoint = H * leftPoint).<br>
152  * @param leftPoints Image points in the left camera, each point corresponds to one point in the right image
153  * @param rightPoints Image points in the right camera
154  * @param pointCorrespondences Number of provided point correspondences, with range [0, infinity), while pointCorrespondences + lineCorrespondences >= 4
155  * @param leftLines Lines in the left camera, each line corresponds to one line in the right image
156  * @param rightLines Lines in the right camera, each line
157  * @param lineCorrespondences Number of provided line correspondences, with range [0, infinity), while pointCorrespondences + lineCorrespondences >= 4
158  * @param right_H_left Resulting homography for the given point correspondences (rightPoint = right_H_left * leftPoint)
159  * @return True, if succeeded
160  * @see homographyMatrixLinear(), affineMatrix(), similarityMatrix().
161  */
162  static bool homographyMatrixFromPointsAndLinesSVD(const Vector2* leftPoints, const Vector2* rightPoints, const size_t pointCorrespondences, const Line2* leftLines, const Line2* rightLines, const size_t lineCorrespondences, SquareMatrix3& right_H_left);
163 
164  /**
165  * Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear, perspective) between two images transforming the projected planar object points between the two images.
166  * This function uses a linear equation to determine an initial homography followed by a non-linear optimization.<br>
167  * The initial homography is not as accurate as the homography determined by a SVD; however, the following optimization steps fix the accuracy while being several magnitudes faster.<br>
168  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
169  * As this function applies the image points in pixel space, the intrinsic camera matrices of both frames are not necessary.
170  * @param leftPoints Image points in the left camera, each point corresponds to one point in the right image
171  * @param rightPoints Image points in the right camera
172  * @param correspondences Number of points correspondences, with range [4, infinity)
173  * @param right_H_left Resulting homography for the given point correspondences (rightPoint = right_H_left * leftPoint)
174  * @param optimizationIterations The number of non-linear-optimization iterations that will be executed after the initial homography has been determined, with range [0, infinity).
175  * @return True, if succeeded
176  * @see homographyMatrixLinearWithOptimizations(), homographyMatrixLinearWithoutOptimations(), homographyMatrixSVD(), affineMatrix(), similarityMatrix().
177  */
178  static bool homographyMatrixLinear(const Vector2* leftPoints, const Vector2* rightPoints, const size_t correspondences, SquareMatrix3& right_H_left, unsigned int optimizationIterations);
179 
180  /**
181  * Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear, perspective) between two images transforming the projected planar object points between the two images.
182  * This function uses a linear equation to determine an initial homography followed by a non-linear optimization.<br>
183  * The initial homography is not as accurate as the homography determined by a SVD; however, the following 10 optimization steps fix the accuracy while being several magnitudes faster (at least for a high number of correspondences).<br>
184  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
185  * As this function applies the image points in pixel space, the intrinsic camera matrices of both frames are not necessary.
186  * @param leftPoints Image points in the left camera, each point corresponds to one point in the right image
187  * @param rightPoints Image points in the right camera
188  * @param correspondences Number of points correspondences, with range [4, infinity)
189  * @param right_H_left Resulting homography for the given point correspondences (rightPoint = right_H_left * leftPoint)
190  * @return True, if succeeded
191  * @see homographyMatrixSVD(), homographyMatrixLinearWithoutOptimations(), affineMatrix(), similarityMatrix().
192  */
193  static inline bool homographyMatrixLinearWithOptimizations(const Vector2* leftPoints, const Vector2* rightPoints, const size_t correspondences, SquareMatrix3& right_H_left);
194 
195  /**
196  * Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear, perspective) between two images transforming the projected planar object points between the two images.
197  * This function uses a linear equation to determine an initial homography followed by a non-linear optimization.<br>
198  * The resulting homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
199  * As this function applies the image points in pixel space, the intrinsic camera matrices of both frames are not necessary.
200  * @param leftPoints Image points in the left camera, each point corresponds to one point in the right image
201  * @param rightPoints Image points in the right camera
202  * @param correspondences Number of points correspondences, with range [4, infinity)
203  * @param right_H_left Resulting homography for the given point correspondences (rightPoint = right_H_left * leftPoint)
204  * @return True, if succeeded
205  * @see homographyMatrixSVD(), homographyMatrixLinearWithOptimizations(), affineMatrix(), similarityMatrix().
206  */
207  static bool homographyMatrixLinearWithoutOptimations(const Vector2* leftPoints, const Vector2* rightPoints, const size_t correspondences, SquareMatrix3& right_H_left);
208 
209  /**
210  * Calculates the affine transformation (6DOF - translation, rotation, scale, aspect ratio, shear) between two sets of 2D image points.
211  * @param leftPoints The image points in the left image, must be valid
212  * @param rightPoints The image points in the right image, one for each point in the left image, must be valid
213  * @param correspondences The number of points correspondences, with range [3, infinity)
214  * @param right_A_left The resulting affine transformation matrix transforming left to right image points
215  * @return True, if succeeded
216  * @see homographyMatrix(), similarityMatrix().
217  */
218  static bool affineMatrix(const ImagePoint* leftPoints, const ImagePoint* rightPoints, const size_t correspondences, SquareMatrix3& right_A_left);
219 
220  /**
221  * Calculates the similarity transformation (4DOF - translation, rotation, scale) between two images transforming the projected planar object points between the two images.
222  * The resulting similarity matrix transforms image points defined in the left image to image points defined in the right image (rightPoint = S * leftPoint).<br>
223  * The resulting 3x3 matrix has the following layout:
224  * <pre>
225  * | a -b tx |
226  * | b a ty |
227  * | 0 0 1 |
228  * </pre>
229  * With 'a' and 'b' defining scale and rotation and 'tx' and 'ty' defining the translation.
230  * As this function applies the image points in pixel space, the intrinsic camera matrices of both frames are not necessary.
231  * @param leftPoints Image points in the left camera, each point corresponds to one point in the right image
232  * @param rightPoints Image points in the right camera
233  * @param correspondences Number of points correspondences, with range [2, infinity)
234  * @param right_S_left The resulting similarity transformation matrix transforming left points to right points
235  * @return True, if succeeded
236  * @see homographyMatrix(), affineMatrix(), homotheticMatrix().
237  */
238  static bool similarityMatrix(const ImagePoint* leftPoints, const ImagePoint* rightPoints, const size_t correspondences, SquareMatrix3& right_S_left);
239 
240  /**
241  * Calculates the homothetic transformation (3DOF - translation, scale) between two sets of image points.
242  * The resulting homothetic matrix transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
243  * The resulting 3x3 matrix has the following layout:
244  * <pre>
245  * | s 0 tx |
246  * | 0 s ty |
247  * | 0 0 1 |
248  * </pre>
249  * With 's' defining scale and 'tx' and 'ty' defining the translation.
250  * @param leftPoints Image points in the left image, each point corresponds to one point in the right image
251  * @param rightPoints Image points in the right image, each point corresponds to one point in the left image
252  * @param correspondences Number of points correspondences, with range [2, infinity)
253  * @param right_H_left Resulting homothetic transformation matrix for the given image points (rightPoint = H * leftPoint)
254  * @return True, if succeeded
255  * @see homographyMatrix(), affineMatrix(), similarityMatrix().
256  */
257  static bool homotheticMatrix(const ImagePoint* leftPoints, const ImagePoint* rightPoints, const size_t correspondences, SquareMatrix3& right_H_left);
258 
259  /**
260  * Factorizes a homography which contains only a rotational part into the corresponding rotation (of the right camera).
261  * The given homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).<br>
262  * Beware: Depending on the accuracy of the given homography (e.g., whether it might contain a tiny translational part) the resulting rotation matrix needs to be adjusted further.<br>
263  * @param homography the homography which will be factorized
264  * @param leftCamera Profile of the left camera object
265  * @param rightCamera Profile of the right camera object
266  * @return The rotation matrix which transforms points defined in the right camera coordinate system into points defined in the left camera coordinate system
267  */
268  static SquareMatrix3 factorizeHomographyMatrix(const SquareMatrix3& homography, const PinholeCamera& leftCamera, const PinholeCamera& rightCamera);
269 
270  /**
271  * Factorizes a planar homography into translation and rotation of the camera.
272  * The resulting factorization provides the camera pose for the right camera while the left camera has the identity camera pose.<br>
273  * Further, a plane normal is provided which is defined in relation to the left camera coordinate system.<br>
274  * Two individual camera poses and normals are provided as the factorization cannot be determined uniquely.
275  * @param right_H_left The homography transforming left points to right points, must be valid
276  * @param leftCamera The camera profile defining the projection of the left camera, must be valid
277  * @param rightCamera The camera profile defining the projection of the right camera, must be valid
278  * @param leftImagePoints The image points in the left camera frame (projected 3D plane object points) that have been used to determine the homography
279  * @param rightImagePoints The image points in the right camera frame, each point corresponds to one point in the left camera frame
280  * @param correspondences The number of image point correspondences, with range [2, infinity)
281  * @param world_T_rightCameras Two resulting camera poses for the right cameras, with default camera pointing towards the negative z-space with y-axis upwards
282  * @param normals Two resulting plane normals (one for each transformation), the normals are defined in relation to the left camera coordinate system
283  * @return True, if succeeded
284  */
285  static bool factorizeHomographyMatrix(const SquareMatrix3& right_H_left, const PinholeCamera& leftCamera, const PinholeCamera& rightCamera, const ImagePoint* leftImagePoints, const ImagePoint* rightImagePoints, const size_t correspondences, HomogenousMatrix4 world_T_rightCameras[2], Vector3 normals[2]);
286 
287  /**
288  * Factorizes a planar homography into translation and rotation of the camera.
289  * The resulting factorization provides the camera pose for the right camera.<br>
290  * Further, a plane normal is provided which is defined in relation to the left camera coordinate system.<br>
291  * Two individual camera poses and normals are provided as the factorization cannot be determined uniquely.
292  * @param right_H_left The homography transforming left points to right points, must be valid
293  * @param world_T_leftCamera The camera pose of the left camera, with default camera pointing towards the negative z-space with y-axis upwards, must be valid
294  * @param leftCamera The camera profile defining the projection of the left camera, must be valid
295  * @param rightCamera The camera profile defining the projection of the right camera, must be valid
296  * @param leftImagePoints Image points in the left camera frame (projected 3D plane object points) that have been used to determine the homography
297  * @param rightImagePoints Image points in the right camera frame, each point corresponds to one point in the left camera frame
298  * @param correspondences The number of image point correspondences, with range [2, infinity)
299  * @param world_T_rightCameras Two resulting camera poses for the right cameras, with default camera pointing towards the negative z-space with y-axis upwards
300  * @param normals Two resulting plane normals (one for each transformation), the normals are defined in relation to the world coordinate system
301  * @return True, if succeeded
302  */
303  static bool factorizeHomographyMatrix(const SquareMatrix3& right_H_left, const HomogenousMatrix4& world_T_leftCamera, const PinholeCamera& leftCamera, const PinholeCamera& rightCamera, const ImagePoint* leftImagePoints, const ImagePoint* rightImagePoints, const size_t correspondences, HomogenousMatrix4 world_T_rightCameras[2], Vector3 normals[2]);
304 
305  /**
306  * Calculates the homography for given 3D object points lying on the Z == 0 plane and corresponding 2D image points.
307  * The resulting homography transforms the object points to the image points (imagePoint = H * objectPoint).<br>
308  * Or more precisely: (imagePointX, imagePointY, 1) = H * (objectPointX, objectPointY, 1)
309  * @param objectPoints 3D object points (with z-axis value equal zero), must be valid
310  * @param imagePoints 2D image points each corresponding to an object point, must be valid
311  * @param correspondences The number of given point correspondences, with range [10, infinity)
312  * @param homography The resulting homography
313  * @return True, if succeeded
314  */
315  static bool homographyMatrixPlaneXY(const ObjectPoint* objectPoints, const ImagePoint* imagePoints, const size_t correspondences, SquareMatrix3& homography);
316 
317  /**
318  * Calculates the homography for given 3D object points lying on the Z == 0 plane and 2D image points.
319  * @param objectPoints 2D object points with z-axis value equal zero, must be valid
320  * @param imagePoints 2D image points each corresponding the to an object point, must be valid
321  * @param correspondences Number of given correspondences, with range [10, infinity)
322  * @param homography The resulting homography
323  * @return True, if succeeded
324  */
325  static bool homographyMatrixPlaneXY(const ImagePoint* objectPoints, const ImagePoint* imagePoints, const size_t correspondences, SquareMatrix3& homography);
326 
327  /**
328  * Normalizes a given homography forcing a 1 in the lower right matrix corner.
329  * @param homography The homography to normalize, must be valid
330  * @return Normalized homography
331  * @tparam T The data type of the scalar to be used, either 'float' or 'double'
332  */
333  template <typename T>
334  static inline SquareMatrixT3<T> normalizedHomography(const SquareMatrixT3<T>& homography);
335 
336  /**
337  * Normalizes a given homography forcing a 1 in the lower right matrix corner.
338  * @param homography The homography to be normalized, must be valid
339  * @tparam T The data type of the scalar to be used, either 'float' or 'double'
340  */
341  template <typename T>
342  static inline void normalizeHomography(SquareMatrixT3<T>& homography);
343 
344  /**
345  * Scales a given homography so that it fits to an individually scaled input image and an individually scaled output image.
346  * @param homography The homography converting points defined in the left image to points defined in the right image (rightPoint = H * leftPoint)
347  * @param scaleLeft The scale which will be applied to the left image, e.g., a scale of 2 means that the image is twice as large, with range (0, infinity)
348  * @param scaleRight The scale which will be applied to the right image, e.g., a scale of 2 means that the image is twice as large, with range (0, infinity)
349  * @tparam T the element type of the homography matrix, e.g., 'float' or 'double'
350  */
351  template <typename T>
352  static inline SquareMatrixT3<T> scaleHomography(const SquareMatrixT3<T>& homography, const T& scaleLeft, const T& scaleRight);
353 
354  /**
355  * Returns whether a given homography represents a plausible transformation.
356  * A homography is voted as plausible as long as the transformed frame corners form a convex shape.<br>
357  * The forward transformation as well as the backward transformation (the inverse) is tested.<br>
358  * The homography transforms image points defined in the left image to image points defined in the right image (rightPoint = H * leftPoint).
359  * @param leftImageWidth The width of the left image in pixel, with range [1, infinity)
360  * @param leftImageHeight The height of the left image in pixel, with range [1, infinity)
361  * @param rightImageWidth The width of the left image in pixel, with range [1, infinity)
362  * @param rightImageHeight The height of the left image in pixel, with range [1, infinity)
363  * @param homography The homography transforming points defined in the left image to points defined in the right image, must be valid
364  * @return True, if the homography is plausible
365  */
366  static bool isHomographyPlausible(const unsigned int leftImageWidth, const unsigned int leftImageHeight, const unsigned int rightImageWidth, const unsigned int rightImageHeight, const SquareMatrix3& homography);
367 
368  /**
369  * Calculates the intrinsic camera matrix for a set of given homographies transforming 3D object points from the z=0 plane to the image plane.
370  * @param homographies Set of given homographies
371  * @param number The number of given homographies with range [3, infinity)
372  * @param intrinsic Resulting intrinsic camera matrix
373  * @return True, if succeeded
374  */
375  static bool intrinsicMatrix(const SquareMatrix3* homographies, const size_t number, SquareMatrix3& intrinsic);
376 
377  /**
378  * Calculates the extrinsic camera matrix for a given intrinsic camera matrix and a corresponding homography transforming 3D object points from the z=0 plane to the image plane.
379  * @param intrinsic The intrinsic camera matrix to return the extrinsic camera matrix for
380  * @param homography The homography corresponding to the intrinsic camera matrix
381  * @param world_T_camera The resulting extrinsic camera matrix (the camera pose), with default camera pointing towards the negative z-space with y-axis upwards
382  * @return True, if succeeded
383  */
384  static bool extrinsicMatrix(const SquareMatrix3& intrinsic, const SquareMatrix3& homography, HomogenousMatrix4& world_T_camera);
385 
386  /**
387  * Calculates the first two radial distortion parameter.
388  * The distortion parameters are determined for several different extrinsic camera positions.<br>
389  * The more point correspondences for individual extrinsic camera positions are provided the more accurate the result.
390  * @param extrinsics Set of extrinsic camera parameters
391  * @param intrinsic The intrinsic camera matrix used for all point correspondences
392  * @param objectPointGroups The groups of object points, each group corresponds to a group of image points and to one extrinsic camera
393  * @param imagePointGroups The groups of image points, each group corresponds to a set of object points
394  * @param distortion2 Resulting first radial distortion parameter for the square distance (r^2)
395  * @param distortion4 Resulting second radial distortion parameter for the square of the square distance (r^4)
396  * @return True, if succeeded
397  */
398  static bool distortionParameters(const ConstIndexedAccessor<HomogenousMatrix4>& extrinsics, const SquareMatrix3& intrinsic, const ConstIndexedAccessor<Vectors3>& objectPointGroups, const ConstIndexedAccessor<Vectors2>& imagePointGroups, Scalar& distortion2, Scalar& distortion4);
399 
400  /**
401  * Converts a given homography determined for a coarser pyramid layer to a homography matching with the finest pyramid layer.
402  * The new homography is determined via:
403  * <pre>
404  * finestHomography = upsample * coarseHomography * downsample
405  * </pre>
406  * @param coarseHomography The homography determined for the coarser pyramid layer, must be valid
407  * @param sourceLayer The index of the coarser pyramid layer, with range [0, infinity)
408  * @return The homography matching with the finest pyramid layer, 'homography' if 'sourceLayer == 0'
409  */
410  static SquareMatrix3 toFinestHomography(const SquareMatrix3& coarseHomography, const unsigned int sourceLayer);
411 
412  /**
413  * Converts a given homography determined for the finest pyramid layer to a homography matching with a coarser pyramid layer.
414  * The new homography is determined via:
415  * <pre>
416  * coarseHomography = downsample * finestHomography * upsample
417  * </pre>
418  * @param finestHomography The homography determined for the finest pyramid layer, must be valid
419  * @param targetLayer The index of the coarser pyramid layer, with range [0, infinity)
420  * @return The homography matching with the coarser pyramid layer, 'homography' if 'targetLayer == 0'
421  */
422  static SquareMatrix3 toCoarseHomography(const SquareMatrix3& finestHomography, const unsigned int targetLayer);
423 
424  /**
425  * Returns the homography transforming lines from one image to another image based on a homography transforming points from one image to another image.
426  * This function is mainly returning:
427  * <pre>
428  * (homographyForPoints^T)^-1
429  * </pre>
430  * @param homographyForPoints The homography transforming points from one image to another image, must be valid
431  * @return The homography allowing to transform lines
432  * @tparam T The data type of the matrix's scalar type, either 'float' or 'double'
433  */
434  template <typename T>
435  static inline SquareMatrixT3<T> homographyForLines(const SquareMatrixT3<T>& homographyForPoints);
436 };
437 
438 inline bool Homography::homographyMatrix(const Vector2* leftPoints, const Vector2* rightPoints, const size_t correspondences, SquareMatrix3& right_H_left, const bool useSVD)
439 {
440  ocean_assert(leftPoints && rightPoints && correspondences >= 4);
441 
442  if (useSVD)
443  {
444  return homographyMatrixSVD(leftPoints, rightPoints, correspondences, right_H_left);
445  }
446  else
447  {
448  return homographyMatrixLinearWithOptimizations(leftPoints, rightPoints, correspondences, right_H_left);
449  }
450 }
451 
452 inline bool Homography::homographyMatrixLinearWithOptimizations(const Vector2* leftPoints, const Vector2* rightPoints, const size_t correspondences, SquareMatrix3& right_H_left)
453 {
454  ocean_assert(leftPoints && rightPoints && correspondences >= 4);
455 
456  return homographyMatrixLinear(leftPoints, rightPoints, correspondences, right_H_left, 10u);
457 }
458 
459 template <typename T>
461 {
462  return Normalization::normalizedTransformation(homography);
463 }
464 
465 template <typename T>
467 {
469 }
470 
471 template <typename T>
472 inline SquareMatrixT3<T> Homography::scaleHomography(const SquareMatrixT3<T>& homography, const T& scaleLeft, const T& scaleRight)
473 {
474  ocean_assert(!homography.isSingular());
475  ocean_assert(scaleLeft > NumericT<T>::eps() && scaleRight > NumericT<T>::eps());
476 
477  // RTr * rHl * lTL
478 
479  const T invScaleLeft = T(1) / scaleLeft;
480 
481  SquareMatrix3 scaledHomography;
482 
483  scaledHomography[0] = homography[0] * scaleRight * invScaleLeft;
484  scaledHomography[1] = homography[1] * scaleRight * invScaleLeft;
485  scaledHomography[2] = homography[2] * invScaleLeft;
486 
487  scaledHomography[3] = homography[3] * scaleRight * invScaleLeft;
488  scaledHomography[4] = homography[4] * scaleRight * invScaleLeft;
489  scaledHomography[5] = homography[5] * invScaleLeft;
490 
491  scaledHomography[6] = homography[6] * scaleRight;
492  scaledHomography[7] = homography[7] * scaleRight;
493  scaledHomography[8] = homography[8];
494 
495 #ifdef OCEAN_DEBUG
496  const SquareMatrix3 rightTransformation(VectorT3<T>(scaleRight, 0, 0), VectorT3<T>(0, scaleRight, 0), VectorT3<T>(0, 0, 1)); // RTr
497  const SquareMatrix3 leftTransformation(VectorT3<T>(scaleLeft, 0, 0), VectorT3<T>(0, scaleLeft, 0), VectorT3<T>(0, 0, 1)); // lTL
498  ocean_assert(scaledHomography.isEqual(rightTransformation * homography * leftTransformation.inverted(), NumericT<T>::weakEps()));
499 #endif
500 
501  return scaledHomography;
502 }
503 
504 template <typename T>
506 {
507  ocean_assert(homographyForPoints.isHomography());
508 
509  return homographyForPoints.transposed().inverted();
510 }
511 
512 }
513 
514 }
515 
516 #endif // META_OCEAN_GEOMETRY_HOMOGRAPHY_H
This class implements the abstract base class for all AnyCamera objects.
Definition: AnyCamera.h:130
This class implements functions necessary for computations with homographies.
Definition: Homography.h:33
static bool extrinsicMatrix(const SquareMatrix3 &intrinsic, const SquareMatrix3 &homography, HomogenousMatrix4 &world_T_camera)
Calculates the extrinsic camera matrix for a given intrinsic camera matrix and a corresponding homogr...
static bool factorizeHomographyMatrix(const SquareMatrix3 &right_H_left, const PinholeCamera &leftCamera, const PinholeCamera &rightCamera, const ImagePoint *leftImagePoints, const ImagePoint *rightImagePoints, const size_t correspondences, HomogenousMatrix4 world_T_rightCameras[2], Vector3 normals[2])
Factorizes a planar homography into translation and rotation of the camera.
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 homotheticMatrix(const ImagePoint *leftPoints, const ImagePoint *rightPoints, const size_t correspondences, SquareMatrix3 &right_H_left)
Calculates the homothetic transformation (3DOF - translation, scale) between two sets of image points...
static SquareMatrix3 toFinestHomography(const SquareMatrix3 &coarseHomography, const unsigned int sourceLayer)
Converts a given homography determined for a coarser pyramid layer to a homography matching with the ...
static SquareMatrix3 homographyMatrix(const PinholeCamera &pinholeCamera, const HomogenousMatrix4 &pose, const Vector3 &patternObjectPointTopLeft, const Vector3 &patternObjectPointBottomLeft, const Vector3 &patternObjectPointTopRight, const unsigned int patternWidth, const unsigned int patternHeight)
Calculates the homography that transforms points defined in a (planar) pattern image to points define...
static bool distortionParameters(const ConstIndexedAccessor< HomogenousMatrix4 > &extrinsics, const SquareMatrix3 &intrinsic, const ConstIndexedAccessor< Vectors3 > &objectPointGroups, const ConstIndexedAccessor< Vectors2 > &imagePointGroups, Scalar &distortion2, Scalar &distortion4)
Calculates the first two radial distortion parameter.
static bool homographyMatrixLinear(const Vector2 *leftPoints, const Vector2 *rightPoints, const size_t correspondences, SquareMatrix3 &right_H_left, unsigned int optimizationIterations)
Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear,...
static bool homographyMatrixLinearWithOptimizations(const Vector2 *leftPoints, const Vector2 *rightPoints, const size_t correspondences, SquareMatrix3 &right_H_left)
Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear,...
Definition: Homography.h:452
static SquareMatrix3 factorizeHomographyMatrix(const SquareMatrix3 &homography, const PinholeCamera &leftCamera, const PinholeCamera &rightCamera)
Factorizes a homography which contains only a rotational part into the corresponding rotation (of the...
static SquareMatrix3 homographyMatrix(const Quaternion &left_T_right, const PinholeCamera &leftCamera, const PinholeCamera &rightCamera)
Deprecated.
static SquareMatrix3 homographyMatrix(const Quaternion &left_T_right, const AnyCamera &leftCamera, const AnyCamera &rightCamera)
Calculates the homography between two images transforming the projected planar object points between ...
static bool intrinsicMatrix(const SquareMatrix3 *homographies, const size_t number, SquareMatrix3 &intrinsic)
Calculates the intrinsic camera matrix for a set of given homographies transforming 3D object points ...
static bool homographyMatrixPlaneXY(const ImagePoint *objectPoints, const ImagePoint *imagePoints, const size_t correspondences, SquareMatrix3 &homography)
Calculates the homography for given 3D object points lying on the Z == 0 plane and 2D image points.
static SquareMatrix3 homographyMatrix(const HomogenousMatrix4 &poseLeft, const HomogenousMatrix4 &poseRight, const PinholeCamera &leftCamera, const PinholeCamera &rightCamera, const Plane3 &plane)
Calculates the homography between two images transforming the projected planar object points between ...
static SquareMatrix3 homographyMatrix(const Quaternion &world_R_left, const Quaternion &world_R_right, const PinholeCamera &leftCamera, const PinholeCamera &rightCamera)
Calculates the homography between two images transforming the projected planar object points between ...
static bool homographyMatrixFromPointsAndLinesSVD(const Vector2 *leftPoints, const Vector2 *rightPoints, const size_t pointCorrespondences, const Line2 *leftLines, const Line2 *rightLines, const size_t lineCorrespondences, SquareMatrix3 &right_H_left)
Calculates the homography (8DOF - translation, rotation, scale, aspect ratio, shear,...
static SquareMatrix3 toCoarseHomography(const SquareMatrix3 &finestHomography, const unsigned int targetLayer)
Converts a given homography determined for the finest pyramid layer to a homography matching with a c...
static SquareMatrix3 homographyMatrix(const HomogenousMatrix4 &world_T_rightCamera, const PinholeCamera &leftCamera, const PinholeCamera &rightCamera, const Plane3 &plane)
Calculates the homography between two images transforming the projected planar object points between ...
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,...
static SquareMatrixT3< T > scaleHomography(const SquareMatrixT3< T > &homography, const T &scaleLeft, const T &scaleRight)
Scales a given homography so that it fits to an individually scaled input image and an individually s...
Definition: Homography.h:472
static SquareMatrixT3< T > normalizedHomography(const SquareMatrixT3< T > &homography)
Normalizes a given homography forcing a 1 in the lower right matrix corner.
Definition: Homography.h:460
static bool homographyMatrixPlaneXY(const ObjectPoint *objectPoints, const ImagePoint *imagePoints, const size_t correspondences, SquareMatrix3 &homography)
Calculates the homography for given 3D object points lying on the Z == 0 plane and corresponding 2D i...
static bool affineMatrix(const ImagePoint *leftPoints, const ImagePoint *rightPoints, const size_t correspondences, SquareMatrix3 &right_A_left)
Calculates the affine transformation (6DOF - translation, rotation, scale, aspect ratio,...
static SquareMatrixT3< T > homographyForLines(const SquareMatrixT3< T > &homographyForPoints)
Returns the homography transforming lines from one image to another image based on a homography trans...
Definition: Homography.h:505
static bool factorizeHomographyMatrix(const SquareMatrix3 &right_H_left, const HomogenousMatrix4 &world_T_leftCamera, const PinholeCamera &leftCamera, const PinholeCamera &rightCamera, const ImagePoint *leftImagePoints, const ImagePoint *rightImagePoints, const size_t correspondences, HomogenousMatrix4 world_T_rightCameras[2], Vector3 normals[2])
Factorizes a planar homography into translation and rotation of the camera.
static bool isHomographyPlausible(const unsigned int leftImageWidth, const unsigned int leftImageHeight, const unsigned int rightImageWidth, const unsigned int rightImageHeight, const SquareMatrix3 &homography)
Returns whether a given homography represents a plausible transformation.
static bool similarityMatrix(const ImagePoint *leftPoints, const ImagePoint *rightPoints, const size_t correspondences, SquareMatrix3 &right_S_left)
Calculates the similarity transformation (4DOF - translation, rotation, scale) between two images tra...
static void normalizeTransformation(SquareMatrixT3< T > &transformation)
Normalizes a given 3x3 transformation matrix which is defined up to a scale factor forcing a 1 in the...
Definition: Normalization.h:75
static SquareMatrixT3< T > normalizedTransformation(const SquareMatrixT3< T > &transformation)
Normalizes a given 3x3 transformation matrix which is defined up to a scale factor forcing a 1 in the...
Definition: Normalization.h:58
This class implements an infinite line in 2D space.
Definition: Line2.h:83
This class provides basic numeric functionalities.
Definition: Numeric.h:57
bool isEqual(const SquareMatrixT3< T > &matrix, const T eps=NumericT< T >::eps()) const
Returns whether two matrices are almost identical up to a specified epsilon.
Definition: SquareMatrix3.h:1386
SquareMatrixT3< T > transposed() const
Returns the transposed of this matrix.
Definition: SquareMatrix3.h:1144
bool isHomography() const
Returns true if this matrix is perspective transform/homography.
Definition: SquareMatrix3.h:1359
SquareMatrixT3< T > inverted() const
Returns the inverted matrix of this matrix.
Definition: SquareMatrix3.h:1176
bool isSingular() const
Returns whether this matrix is singular (and thus cannot be inverted).
Definition: SquareMatrix3.h:1341
float Scalar
Definition of a scalar type.
Definition: Math.h:128
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15