Blender  V3.3
homography_test.cc
Go to the documentation of this file.
1 // Copyright (c) 2011 libmv authors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 // IN THE SOFTWARE.
20 
22 #include "libmv/logging/logging.h"
24 #include "testing/testing.h"
25 
26 namespace {
27 using namespace libmv;
28 
29 namespace {
30 
31 // Check whether homography transform M actually transforms
32 // given vectors x1 to x2. Used to check validness of a reconstructed
33 // homography matrix.
34 // TODO(sergey): Consider using this in all tests since possible homography
35 // matrix is not fixed to a single value and different-looking matrices
36 // might actually crrespond to the same exact transform.
37 void CheckHomography2DTransform(const Mat3& H, const Mat& x1, const Mat& x2) {
38  for (int i = 0; i < x2.cols(); ++i) {
39  Vec3 x2_expected = x2.col(i);
40  Vec3 x2_observed = H * x1.col(i);
41  x2_observed /= x2_observed(2);
42  EXPECT_MATRIX_NEAR(x2_expected, x2_observed, 1e-8);
43  }
44 }
45 
46 } // namespace
47 
48 TEST(Homography2DTest, Rotation45AndTranslationXY) {
49  Mat x1(3, 4);
50  // clang-format off
51  x1 << 0, 1, 0, 5,
52  0, 0, 2, 3,
53  1, 1, 1, 1;
54  // clang-format on
55 
56  double angle = 45.0;
57  Mat3 m;
58  // clang-format off
59  m << cos(angle), -sin(angle), -2,
60  sin(angle), cos(angle), 5,
61  0, 0, 1;
62  // clang-format on
63 
64  Mat x2 = x1;
65  // Transform point from ground truth matrix
66  for (int i = 0; i < x2.cols(); ++i)
67  x2.col(i) = m * x1.col(i);
68 
69  Mat3 homography_mat;
70  EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
71  VLOG(1) << "Mat Homography2D ";
72  VLOG(1) << homography_mat;
73  VLOG(1) << "Mat GT ";
74  VLOG(1) << m;
75  EXPECT_MATRIX_NEAR(homography_mat, m, 1e-8);
76 }
77 
78 TEST(Homography2DTest, AffineGeneral4) {
79  // TODO(julien) find why it doesn't work with 4 points!!!
80  Mat x1(3, 4);
81  // clang-format off
82  x1 << 0, 1, 0, 2,
83  0, 0, 1, 2,
84  1, 1, 1, 1;
85  // clang-format on
86  Mat3 m;
87  // clang-format off
88  m << 3, -1, 4,
89  6, -2, -3,
90  0, 0, 1;
91  // clang-format on
92 
93  Mat x2 = x1;
94  for (int i = 0; i < x2.cols(); ++i) {
95  x2.col(i) = m * x1.col(i);
96  }
97 
98  Mat3 homography_mat;
99  EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
100  VLOG(1) << "Mat Homography2D";
101  VLOG(1) << homography_mat;
102  CheckHomography2DTransform(homography_mat, x1, x2);
103 
104  // Test with euclidean coordinates
105  Mat eX1, eX2;
106  HomogeneousToEuclidean(x1, &eX1);
107  HomogeneousToEuclidean(x2, &eX2);
108  homography_mat.setIdentity();
109  EXPECT_TRUE(Homography2DFromCorrespondencesLinear(eX1, eX2, &homography_mat));
110 
111  VLOG(1) << "Mat Homography2D ";
112  VLOG(1) << homography_mat;
113  CheckHomography2DTransform(homography_mat, x1, x2);
114 }
115 
116 TEST(Homography2DTest, AffineGeneral5) {
117  Mat x1(3, 5);
118  // clang-format off
119  x1 << 0, 1, 0, 2, 5,
120  0, 0, 1, 2, 2,
121  1, 1, 1, 1, 1;
122  // clang-format on
123  Mat3 m;
124  // clang-format off
125  m << 3, -1, 4,
126  6, -2, -3,
127  0, 0, 1;
128  // clang-format on
129 
130  Mat x2 = x1;
131  for (int i = 0; i < x2.cols(); ++i)
132  x2.col(i) = m * x1.col(i);
133 
134  Mat3 homography_mat;
135  EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
136 
137  VLOG(1) << "Mat Homography2D ";
138  VLOG(1) << homography_mat;
139  EXPECT_MATRIX_NEAR(homography_mat, m, 1e-8);
140 
141  // Test with euclidean coordinates
142  Mat eX1, eX2;
143  HomogeneousToEuclidean(x1, &eX1);
144  HomogeneousToEuclidean(x2, &eX2);
145  homography_mat.setIdentity();
146  EXPECT_TRUE(Homography2DFromCorrespondencesLinear(eX1, eX2, &homography_mat));
147 
148  VLOG(1) << "Mat Homography2D ";
149  VLOG(1) << homography_mat;
150  EXPECT_MATRIX_NEAR(homography_mat, m, 1e-8);
151 }
152 
153 TEST(Homography2DTest, HomographyGeneral) {
154  Mat x1(3, 4);
155  // clang-format off
156  x1 << 0, 1, 0, 5,
157  0, 0, 2, 3,
158  1, 1, 1, 1;
159  // clang-format on
160  Mat3 m;
161  // clang-format off
162  m << 3, -1, 4,
163  6, -2, -3,
164  1, -3, 1;
165  // clang-format on
166 
167  Mat x2 = x1;
168  for (int i = 0; i < x2.cols(); ++i)
169  x2.col(i) = m * x1.col(i);
170 
171  Mat3 homography_mat;
172  EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
173 
174  VLOG(1) << "Mat Homography2D ";
175  VLOG(1) << homography_mat;
176  EXPECT_MATRIX_NEAR(homography_mat, m, 1e-8);
177 }
178 
179 TEST(Homography3DTest, RotationAndTranslationXYZ) {
180  Mat x1(4, 5);
181  // clang-format off
182  x1 << 0, 0, 1, 5, 2,
183  0, 1, 2, 3, 5,
184  0, 2, 0, 1, 5,
185  1, 1, 1, 1, 1;
186  // clang-format on
187  Mat4 M;
188  M.setIdentity();
189  /*
190  M = AngleAxisd(45.0, Vector3f::UnitZ())
191  * AngleAxisd(25.0, Vector3f::UnitX())
192  * AngleAxisd(5.0, Vector3f::UnitZ());*/
193 
194  // Rotation on x + translation
195  double angle = 45.0;
196  Mat4 rot;
197  // clang-format off
198  rot << 1, 0, 0, 1,
199  0, cos(angle), -sin(angle), 3,
200  0, sin(angle), cos(angle), -2,
201  0, 0, 0, 1;
202  // clang-format on
203  M *= rot;
204  // Rotation on y
205  angle = 25.0;
206  // clang-format off
207  rot << cos(angle), 0, sin(angle), 0,
208  0, 1, 0, 0,
209  -sin(angle), 0, cos(angle), 0,
210  0, 0, 0, 1;
211  // clang-format on
212  M *= rot;
213  // Rotation on z
214  angle = 5.0;
215  // clang-format off
216  rot << cos(angle), -sin(angle), 0, 0,
217  sin(angle), cos(angle), 0, 0,
218  0, 0, 1, 0,
219  0, 0, 0, 1;
220  // clang-format on
221  M *= rot;
222  Mat x2 = x1;
223  for (int i = 0; i < x2.cols(); ++i) {
224  x2.col(i) = M * x1.col(i);
225  }
226 
227  Mat4 homography_mat;
228  EXPECT_TRUE(Homography3DFromCorrespondencesLinear(x1, x2, &homography_mat));
229 
230  VLOG(1) << "Mat Homography3D " << homography_mat;
231  VLOG(1) << "Mat GT " << M;
232  EXPECT_MATRIX_NEAR(homography_mat, M, 1e-8);
233 }
234 
235 TEST(Homography3DTest, AffineGeneral) {
236  Mat x1(4, 5);
237  // clang-format off
238  x1 << 0, 0, 1, 5, 2,
239  0, 1, 2, 3, 5,
240  0, 2, 0, 1, 5,
241  1, 1, 1, 1, 1;
242  // clang-format on
243  Mat4 m;
244  // clang-format off
245  m << 3, -1, 4, 1,
246  6, -2, -3, -6,
247  1, 0, 1, 2,
248  0, 0, 0, 1;
249  // clang-format on
250 
251  Mat x2 = x1;
252  for (int i = 0; i < x2.cols(); ++i) {
253  x2.col(i) = m * x1.col(i);
254  }
255 
256  Mat4 homography_mat;
257  EXPECT_TRUE(Homography3DFromCorrespondencesLinear(x1, x2, &homography_mat));
258  VLOG(1) << "Mat Homography3D ";
259  VLOG(1) << homography_mat;
260  EXPECT_MATRIX_NEAR(homography_mat, m, 1e-8);
261 }
262 
263 TEST(Homography3DTest, HomographyGeneral) {
264  Mat x1(4, 5);
265  // clang-format off
266  x1 << 0, 0, 1, 5, 2,
267  0, 1, 2, 3, 5,
268  0, 2, 0, 1, 5,
269  1, 1, 1, 1, 1;
270  // clang-format on
271  Mat4 m;
272  // clang-format off
273  m << 3, -1, 4, 1,
274  6, -2, -3, -6,
275  1, 0, 1, 2,
276  -3, 1, 0, 1;
277  // clang-format on
278 
279  Mat x2 = x1;
280  for (int i = 0; i < x2.cols(); ++i) {
281  x2.col(i) = m * x1.col(i);
282  }
283 
284  Mat4 homography_mat;
285  EXPECT_TRUE(Homography3DFromCorrespondencesLinear(x1, x2, &homography_mat));
286  VLOG(1) << "Mat Homography3D";
287  VLOG(1) << homography_mat;
288  EXPECT_MATRIX_NEAR(homography_mat, m, 1e-8);
289 }
290 
291 } // namespace
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
#define rot(x, k)
float[3][3] Mat3
Definition: gpu_matrix.cc:27
#define VLOG(severity)
Definition: log.h:37
#define M
#define H(x, y, z)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
TEST(PolynomialCameraIntrinsics2, ApplyOnFocalCenter)
void HomogeneousToEuclidean(const Mat &H, Mat *X)
Definition: projection.cc:166
Eigen::MatrixXd Mat
Definition: numeric.h:60
bool Homography2DFromCorrespondencesLinear(const Mat &x1, const Mat &x2, Mat3 *H, double expected_precision)
Eigen::Vector3d Vec3
Definition: numeric.h:106
bool Homography3DFromCorrespondencesLinear(const Mat &x1, const Mat &x2, Mat4 *H, double expected_precision)