annotate Framework/Toolbox/FiniteProjectiveCamera.cpp @ 161:197a5ddaf68c wasm

FiniteProjectiveCamera
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 14 Feb 2018 11:29:26 +0100
parents
children 45b03b04a777
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
161
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
1 /**
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
2 * Stone of Orthanc
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
4 * Department, University Hospital of Liege, Belgium
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
6 *
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
7 * This program is free software: you can redistribute it and/or
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
8 * modify it under the terms of the GNU Affero General Public License
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
9 * as published by the Free Software Foundation, either version 3 of
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
10 * the License, or (at your option) any later version.
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
11 *
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
12 * This program is distributed in the hope that it will be useful, but
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
15 * Affero General Public License for more details.
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
16 *
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
17 * You should have received a copy of the GNU Affero General Public License
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
19 **/
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
20
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
21
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
22 #include "FiniteProjectiveCamera.h"
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
23
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
24 #include <Core/Logging.h>
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
25 #include <Core/OrthancException.h>
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
26
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
27 namespace OrthancStone
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
28 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
29 void FiniteProjectiveCamera::ComputeMInverse()
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
30 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
31 using namespace boost::numeric::ublas;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
32
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
33 // inv(M) = inv(K * R) = inv(R) * inv(K) = R' * inv(K). This
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
34 // matrix is always invertible, by definition of finite
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
35 // projective cameras (page 157).
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
36 Matrix kinv;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
37 LinearAlgebra::InvertUpperTriangularMatrix(kinv, k_);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
38 minv_ = prod(trans(r_), kinv);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
39 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
40
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
41
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
42 void FiniteProjectiveCamera::Setup(const Matrix& k,
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
43 const Matrix& r,
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
44 const Vector& c)
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
45 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
46 using namespace boost::numeric::ublas;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
47
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
48 if (k.size1() != 3 ||
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
49 k.size2() != 3 ||
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
50 !LinearAlgebra::IsCloseToZero(k(1, 0)) ||
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
51 !LinearAlgebra::IsCloseToZero(k(2, 0)) ||
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
52 !LinearAlgebra::IsCloseToZero(k(2, 1)))
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
53 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
54 LOG(ERROR) << "Invalid intrinsic parameters";
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
55 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
56 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
57
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
58 if (r.size1() != 3 ||
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
59 r.size2() != 3)
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
60 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
61 LOG(ERROR) << "Invalid size for a 3D rotation matrix";
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
62 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
63 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
64
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
65 if (!LinearAlgebra::IsRotationMatrix(r, 100.0 * std::numeric_limits<float>::epsilon()))
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
66 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
67 LOG(ERROR) << "Invalid rotation matrix";
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
68 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
69 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
70
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
71 if (c.size() != 3)
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
72 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
73 LOG(ERROR) << "Invalid camera center";
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
74 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
75 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
76
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
77 k_ = k;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
78 r_ = r;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
79 c_ = c;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
80
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
81 ComputeMInverse();
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
82
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
83 Matrix tmp = identity_matrix<double>(3);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
84 tmp.resize(3, 4);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
85 tmp(0, 3) = -c[0];
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
86 tmp(1, 3) = -c[1];
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
87 tmp(2, 3) = -c[2];
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
88
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
89 tmp = prod(r, tmp);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
90 p_ = prod(k, tmp);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
91 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
92
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
93
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
94 void FiniteProjectiveCamera::Setup(const Matrix& p)
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
95 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
96 using namespace boost::numeric::ublas;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
97
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
98 if (p.size1() != 3 ||
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
99 p.size2() != 4)
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
100 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
101 LOG(ERROR) << "Invalid camera matrix";
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
102 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
103 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
104
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
105 p_ = p;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
106
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
107 // M is the left 3x3 submatrix of "P"
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
108 Matrix m = p;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
109 m.resize(3, 3);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
110
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
111 // p4 is the last column of "P"
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
112 Vector p4(3);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
113 p4[0] = p(0, 3);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
114 p4[1] = p(1, 3);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
115 p4[2] = p(2, 3);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
116
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
117 // The RQ decomposition is explained on page 157
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
118 LinearAlgebra::RQDecomposition3x3(k_, r_, m);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
119 ComputeMInverse();
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
120
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
121 c_ = prod(-minv_, p4);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
122 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
123
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
124
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
125 FiniteProjectiveCamera::FiniteProjectiveCamera(const double k[9],
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
126 const double r[9],
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
127 const double c[3])
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
128 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
129 Matrix kk, rr;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
130 Vector cc;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
131
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
132 LinearAlgebra::FillMatrix(kk, 3, 3, k);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
133 LinearAlgebra::FillMatrix(rr, 3, 3, r);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
134 LinearAlgebra::FillVector(cc, 3, c);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
135
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
136 Setup(kk, rr, cc);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
137 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
138
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
139
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
140 FiniteProjectiveCamera::FiniteProjectiveCamera(const double p[12])
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
141 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
142 Matrix pp;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
143 LinearAlgebra::FillMatrix(pp, 3, 4, p);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
144 Setup(pp);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
145 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
146
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
147
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
148 Vector FiniteProjectiveCamera::GetRayDirection(double x,
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
149 double y) const
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
150 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
151 // This derives from Equation (6.14) on page 162, taking "mu =
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
152 // 1" and noticing that "-inv(M)*p4" corresponds to the camera
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
153 // center in finite projective cameras
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
154
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
155 // The (x,y) coordinates on the imaged plane, as an homogeneous vector
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
156 Vector xx(3);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
157 xx[0] = x;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
158 xx[1] = y;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
159 xx[2] = 1.0;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
160
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
161 return boost::numeric::ublas::prod(minv_, xx);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
162 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
163
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
164
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
165
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
166 static Vector SetupApply(const Vector& v,
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
167 bool infinityAllowed)
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
168 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
169 if (v.size() == 3)
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
170 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
171 // Vector "v" in non-homogeneous coordinates, add the homogeneous component
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
172 Vector vv;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
173 LinearAlgebra::AssignVector(vv, v[0], v[1], v[2], 1.0);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
174 return vv;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
175 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
176 else if (v.size() == 4)
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
177 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
178 // Vector "v" is already in homogeneous coordinates
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
179
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
180 if (!infinityAllowed &&
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
181 LinearAlgebra::IsCloseToZero(v[3]))
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
182 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
183 LOG(ERROR) << "Cannot apply a finite projective camera to a "
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
184 << "point at infinity with this method";
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
185 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
186 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
187
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
188 return v;
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
189 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
190 else
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
191 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
192 LOG(ERROR) << "The input vector must represent a point in 3D";
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
193 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
194 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
195 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
196
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
197
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
198 void FiniteProjectiveCamera::ApplyFinite(double& x,
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
199 double& y,
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
200 const Vector& v) const
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
201 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
202 Vector p = boost::numeric::ublas::prod(p_, SetupApply(v, false));
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
203
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
204 if (LinearAlgebra::IsCloseToZero(p[2]))
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
205 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
206 // Point at infinity: Should not happen with a finite input point
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
207 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
208 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
209 else
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
210 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
211 x = p[0] / p[2];
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
212 y = p[1] / p[2];
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
213 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
214 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
215
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
216
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
217 Vector FiniteProjectiveCamera::ApplyGeneral(const Vector& v) const
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
218 {
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
219 return boost::numeric::ublas::prod(p_, SetupApply(v, true));
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
220 }
197a5ddaf68c FiniteProjectiveCamera
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
221 }