Blender V4.3
homography_error.h
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
21#ifndef LIBMV_MULTIVIEW_HOMOGRAPHY_ERRORS_H_
22#define LIBMV_MULTIVIEW_HOMOGRAPHY_ERRORS_H_
23
25
26namespace libmv {
27namespace homography {
28namespace homography2D {
29
50 static void Residuals(const Mat& H, const Mat& x1, const Mat& x2, Mat2X* dx) {
51 dx->resize(2, x1.cols());
52 Mat3X x2h_est;
53 if (x1.rows() == 2) {
54 x2h_est = H * EuclideanToHomogeneous(static_cast<Mat2X>(x1));
55 } else {
56 x2h_est = H * x1;
57 }
58 dx->row(0) = x2h_est.row(0).array() / x2h_est.row(2).array();
59 dx->row(1) = x2h_est.row(1).array() / x2h_est.row(2).array();
60 if (x2.rows() == 2) {
61 *dx = x2 - *dx;
62 } else {
63 *dx = HomogeneousToEuclidean(static_cast<Mat3X>(x2)) - *dx;
64 }
65 }
78 static void Residuals(const Mat& H, const Vec& x1, const Vec& x2, Vec2* dx) {
79 Vec3 x2h_est;
80 if (x1.rows() == 2) {
81 x2h_est = H * EuclideanToHomogeneous(static_cast<Vec2>(x1));
82 } else {
83 x2h_est = H * x1;
84 }
85 if (x2.rows() == 2) {
86 *dx = x2 - x2h_est.head<2>() / x2h_est[2];
87 } else {
88 *dx = HomogeneousToEuclidean(static_cast<Vec3>(x2)) -
89 x2h_est.head<2>() / x2h_est[2];
90 }
91 }
104 static double Error(const Mat& H, const Mat& x1, const Mat& x2) {
105 Mat2X dx;
106 Residuals(H, x1, x2, &dx);
107 return dx.squaredNorm();
108 }
120 static double Error(const Mat& H, const Vec& x1, const Vec& x2) {
121 Vec2 dx;
122 Residuals(H, x1, x2, &dx);
123 return dx.squaredNorm();
124 }
125};
126
147 static double Error(const Mat& H, const Vec& x1, const Vec& x2) {
148 // TODO(keir): This is awesomely inefficient because it does a 3x3
149 // inversion for each evaluation.
150 Mat3 Hinv = H.inverse();
151 return AsymmetricError::Error(H, x1, x2) +
152 AsymmetricError::Error(Hinv, x2, x1);
153 }
154 // TODO(julien) Add residuals function \see AsymmetricError
155};
163 // TODO(julien) Make an AlgebraicError2Rows and AlgebraicError3Rows
164
176 static void Residuals(const Mat& H, const Mat& x1, const Mat& x2, Mat3X* dx) {
177 dx->resize(3, x1.cols());
178 Vec3 col;
179 for (int i = 0; i < x1.cols(); ++i) {
180 Residuals(H, x1.col(i), x2.col(i), &col);
181 dx->col(i) = col;
182 }
183 }
195 static void Residuals(const Mat& H, const Vec& x1, const Vec& x2, Vec3* dx) {
196 Vec3 x2h_est;
197 if (x1.rows() == 2) {
198 x2h_est = H * EuclideanToHomogeneous(static_cast<Vec2>(x1));
199 } else {
200 x2h_est = H * x1;
201 }
202 if (x2.rows() == 2) {
203 *dx = SkewMat(EuclideanToHomogeneous(static_cast<Vec2>(x2))) * x2h_est;
204 } else {
205 *dx = SkewMat(x2) * x2h_est;
206 }
207 // TODO(julien) This is inefficient since it creates an
208 // identical 3x3 skew matrix for each evaluation.
209 }
221 static double Error(const Mat& H, const Mat& x1, const Mat& x2) {
222 Mat3X dx;
223 Residuals(H, x1, x2, &dx);
224 return dx.squaredNorm();
225 }
237 static double Error(const Mat& H, const Vec& x1, const Vec& x2) {
238 Vec3 dx;
239 Residuals(H, x1, x2, &dx);
240 return dx.squaredNorm();
241 }
242};
243// TODO(keir): Add error based on ideal points.
244
245} // namespace homography2D
246// TODO(julien) add homography3D errors
247} // namespace homography
248} // namespace libmv
249
250#endif // LIBMV_MULTIVIEW_HOMOGRAPHY_ERRORS_H_
uint col
#define H(x, y, z)
Eigen::VectorXd Vec
Definition numeric.h:61
void EuclideanToHomogeneous(const Mat &X, Mat *H)
Eigen::Matrix< double, 3, 3 > Mat3
Definition numeric.h:72
Eigen::Vector2d Vec2
Definition numeric.h:105
void HomogeneousToEuclidean(const Mat &H, Mat *X)
Eigen::MatrixXd Mat
Definition numeric.h:60
Mat3 SkewMat(const Vec3 &x)
Returns the skew anti-symmetric matrix of a vector.
Definition numeric.h:470
Eigen::Vector3d Vec3
Definition numeric.h:106
Eigen::Matrix< double, 3, Eigen::Dynamic > Mat3X
Definition numeric.h:92
Eigen::Matrix< double, 2, Eigen::Dynamic > Mat2X
Definition numeric.h:91
static void Residuals(const Mat &H, const Mat &x1, const Mat &x2, Mat3X *dx)
static double Error(const Mat &H, const Mat &x1, const Mat &x2)
static void Residuals(const Mat &H, const Vec &x1, const Vec &x2, Vec3 *dx)
static double Error(const Mat &H, const Vec &x1, const Vec &x2)
static double Error(const Mat &H, const Vec &x1, const Vec &x2)
static void Residuals(const Mat &H, const Mat &x1, const Mat &x2, Mat2X *dx)
static double Error(const Mat &H, const Mat &x1, const Mat &x2)
static void Residuals(const Mat &H, const Vec &x1, const Vec &x2, Vec2 *dx)
static double Error(const Mat &H, const Vec &x1, const Vec &x2)