Mercurial > hg > orthanc-stone
annotate Framework/Toolbox/ShearWarpProjectiveTransform.cpp @ 191:46cb2eedc2e0 wasm
ShearWarpProjectiveTransform
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 16 Mar 2018 15:01:52 +0100 |
parents | |
children | 4abddd083374 |
rev | line source |
---|---|
191
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
1 /** |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
2 * Stone of Orthanc |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
6 * |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
7 * This program is free software: you can redistribute it and/or |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Affero General Public License |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
9 * as published by the Free Software Foundation, either version 3 of |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
10 * the License, or (at your option) any later version. |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
11 * |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
12 * This program is distributed in the hope that it will be useful, but |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
13 * WITHOUT ANY WARRANTY; without even the implied warranty of |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
15 * Affero General Public License for more details. |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
16 * |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Affero General Public License |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
19 **/ |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
20 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
21 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
22 #include "ShearWarpProjectiveTransform.h" |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
23 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
24 #include "ImageGeometry.h" |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
25 #include "Extent2D.h" |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
26 #include "FiniteProjectiveCamera.h" |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
27 #include "GeometryToolbox.h" |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
28 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
29 #include <Core/OrthancException.h> |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
30 #include <Core/Logging.h> |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
31 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
32 #include <boost/numeric/ublas/matrix_proxy.hpp> |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
33 #include <cassert> |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
34 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
35 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
36 namespace OrthancStone |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
37 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
38 static bool IsValidShear(const Matrix& M_shear) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
39 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
40 return (LinearAlgebra::IsCloseToZero(M_shear(0, 1)) && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
41 LinearAlgebra::IsCloseToZero(M_shear(1, 0)) && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
42 LinearAlgebra::IsCloseToZero(M_shear(2, 0)) && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
43 LinearAlgebra::IsCloseToZero(M_shear(2, 1)) && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
44 LinearAlgebra::IsNear(1.0, M_shear(2, 2)) && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
45 LinearAlgebra::IsCloseToZero(M_shear(2, 3)) && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
46 LinearAlgebra::IsCloseToZero(M_shear(3, 0)) && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
47 LinearAlgebra::IsCloseToZero(M_shear(3, 1)) && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
48 LinearAlgebra::IsNear(1.0, M_shear(3, 3))); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
49 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
50 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
51 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
52 static void ComputeShearParameters(double& scaling, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
53 double& offsetX, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
54 double& offsetY, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
55 const Matrix& shear, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
56 double z) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
57 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
58 // Check out: ../../Resources/Computations/ComputeShearParameters.py |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
59 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
60 if (!LinearAlgebra::IsShearMatrix(shear)) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
61 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
62 LOG(ERROR) << "Not a valid shear matrix"; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
63 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
64 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
65 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
66 scaling = 1.0 / (shear(3,2) * z + 1.0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
67 offsetX = shear(0,2) * z * scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
68 offsetY = shear(1,2) * z * scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
69 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
70 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
71 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
72 ShearWarpProjectiveTransform:: |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
73 ShearWarpProjectiveTransform(const Matrix& M_view, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
74 //const Matrix& P, // Permutation applied to the volume |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
75 unsigned int volumeWidth, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
76 unsigned int volumeHeight, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
77 unsigned int volumeDepth, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
78 double pixelSpacingX, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
79 double pixelSpacingY, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
80 unsigned int imageWidth, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
81 unsigned int imageHeight) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
82 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
83 eye_o.resize(4); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
84 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
85 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
86 // Find back the camera center given the "M_view" matrix |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
87 const double m11 = M_view(0, 0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
88 const double m12 = M_view(0, 1); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
89 const double m13 = M_view(0, 2); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
90 const double m14 = M_view(0, 3); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
91 const double m21 = M_view(1, 0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
92 const double m22 = M_view(1, 1); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
93 const double m23 = M_view(1, 2); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
94 const double m24 = M_view(1, 3); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
95 const double m41 = M_view(3, 0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
96 const double m42 = M_view(3, 1); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
97 const double m43 = M_view(3, 2); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
98 const double m44 = M_view(3, 3); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
99 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
100 // Equations (A.8) to (A.11) on page 203. Also check out |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
101 // "Finding the camera center" in "Multiple View Geometry in |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
102 // Computer Vision - 2nd edition", page 163. |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
103 const double vx[9] = { m12, m13, m14, m22, m23, m24, m42, m43, m44 }; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
104 const double vy[9] = { m11, m13, m14, m21, m23, m24, m41, m43, m44 }; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
105 const double vz[9] = { m11, m12, m14, m21, m22, m24, m41, m42, m44 }; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
106 const double vw[9] = { m11, m12, m13, m21, m22, m23, m41, m42, m43 }; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
107 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
108 Matrix m; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
109 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
110 LinearAlgebra::FillMatrix(m, 3, 3, vx); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
111 eye_o[0] = -LinearAlgebra::ComputeDeterminant(m); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
112 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
113 LinearAlgebra::FillMatrix(m, 3, 3, vy); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
114 eye_o[1] = LinearAlgebra::ComputeDeterminant(m); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
115 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
116 LinearAlgebra::FillMatrix(m, 3, 3, vz); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
117 eye_o[2] = -LinearAlgebra::ComputeDeterminant(m); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
118 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
119 LinearAlgebra::FillMatrix(m, 3, 3, vw); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
120 eye_o[3] = LinearAlgebra::ComputeDeterminant(m); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
121 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
122 if (LinearAlgebra::IsCloseToZero(eye_o[3])) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
123 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
124 LOG(ERROR) << "The shear-warp projective transform is not applicable to affine cameras"; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
125 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
126 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
127 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
128 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
129 #if 0 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
130 // Assume "T_shift = I" (the eye does not lie on plane k = 0) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
131 const Matrix T_shift = LinearAlgebra::IdentityMatrix(4); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
132 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
133 // Equation (A.13) on page 204, given that the inverse of a |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
134 // permutation matrix is its transpose (TODO CHECK). If no T_shift |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
135 // or permutation P is applied, M'_view == M_view |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
136 const Matrix MM_view = LinearAlgebra::Product( |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
137 M_view, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
138 LinearAlgebra::Transpose(P), |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
139 LinearAlgebra::InvertScalingTranslationMatrix(T_shift)); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
140 #else |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
141 // This is a shortcut, as we take "T_shift = I" and "P = I" |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
142 const Matrix MM_view = M_view; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
143 #endif |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
144 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
145 // Equation (A.14) on page 207 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
146 Matrix MM_shear = LinearAlgebra::IdentityMatrix(4); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
147 MM_shear(0, 2) = -eye_o[0] / eye_o[2]; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
148 MM_shear(1, 2) = -eye_o[1] / eye_o[2]; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
149 MM_shear(3, 2) = -eye_o[3] / eye_o[2]; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
150 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
151 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
152 // Compute the extent of the intermediate image |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
153 Extent2D extent; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
154 double maxScaling = 1; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
155 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
156 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
157 // Compute the shearing factors of the two extreme planes of the |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
158 // volume (z=0 and z=volumeDepth) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
159 double scaling, offsetX, offsetY; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
160 ComputeShearParameters(scaling, offsetX, offsetY, MM_shear, 0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
161 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
162 if (scaling > 0) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
163 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
164 extent.AddPoint(offsetX, offsetY); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
165 extent.AddPoint(offsetX + static_cast<double>(volumeWidth) * scaling, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
166 offsetY + static_cast<double>(volumeHeight) * scaling); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
167 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
168 if (scaling > maxScaling) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
169 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
170 maxScaling = scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
171 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
172 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
173 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
174 ComputeShearParameters(scaling, offsetX, offsetY, MM_shear, volumeDepth); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
175 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
176 if (scaling > 0) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
177 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
178 extent.AddPoint(offsetX, offsetY); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
179 extent.AddPoint(offsetX + static_cast<double>(volumeWidth) * scaling, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
180 offsetY + static_cast<double>(volumeHeight) * scaling); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
181 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
182 if (scaling > maxScaling) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
183 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
184 maxScaling = scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
185 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
186 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
187 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
188 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
189 if (LinearAlgebra::IsCloseToZero(extent.GetWidth()) || |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
190 LinearAlgebra::IsCloseToZero(extent.GetHeight())) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
191 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
192 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
193 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
194 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
195 intermediateWidth_ = std::ceil(extent.GetWidth() / maxScaling); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
196 intermediateHeight_ = std::ceil(extent.GetHeight() / maxScaling); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
197 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
198 // This is the product "T * S" in Equation (A.16) on page 209 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
199 Matrix TS = LinearAlgebra::Product( |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
200 GeometryToolbox::CreateTranslationMatrix(static_cast<double>(intermediateWidth_) / 2.0, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
201 static_cast<double>(intermediateHeight_) / 2.0, 0), |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
202 GeometryToolbox::CreateScalingMatrix(1.0 / maxScaling, 1.0 / maxScaling, 1), |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
203 GeometryToolbox::CreateTranslationMatrix(-extent.GetCenterX(), -extent.GetCenterY(), 0)); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
204 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
205 // This is Equation (A.16) on page 209. WARNING: There is an |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
206 // error in Lacroute's thesis: "inv(MM_shear)" is used instead |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
207 // of "MM_shear". |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
208 M_shear = LinearAlgebra::Product(TS, MM_shear); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
209 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
210 if (!IsValidShear(M_shear)) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
211 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
212 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
213 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
214 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
215 // This is Equation (A.17) on page 209 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
216 Matrix tmp; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
217 LinearAlgebra::InvertMatrix(tmp, M_shear); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
218 M_warp = LinearAlgebra::Product(MM_view, tmp); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
219 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
220 // Intrinsic parameters of the camera |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
221 k_ = LinearAlgebra::ZeroMatrix(3, 4); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
222 k_(0, 0) = 1.0 / pixelSpacingX; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
223 k_(0, 3) = static_cast<double>(imageWidth) / 2.0; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
224 k_(1, 1) = 1.0 / pixelSpacingY; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
225 k_(1, 3) = static_cast<double>(imageHeight) / 2.0; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
226 k_(2, 3) = 1.0; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
227 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
228 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
229 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
230 FiniteProjectiveCamera *ShearWarpProjectiveTransform::CreateCamera() const |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
231 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
232 Matrix p = LinearAlgebra::Product(k_, M_warp, M_shear); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
233 return new FiniteProjectiveCamera(p); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
234 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
235 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
236 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
237 void ShearWarpProjectiveTransform::ComputeShearOnSlice(double& a11, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
238 double& b1, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
239 double& a22, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
240 double& b2, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
241 double& shearedZ, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
242 const double sourceZ) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
243 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
244 // Check out: ../../Resources/Computations/ComputeShearOnSlice.py |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
245 assert(IsValidShear(M_shear)); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
246 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
247 const double s11 = M_shear(0, 0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
248 const double s13 = M_shear(0, 2); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
249 const double s14 = M_shear(0, 3); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
250 const double s22 = M_shear(1, 1); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
251 const double s23 = M_shear(1, 2); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
252 const double s24 = M_shear(1, 3); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
253 const double s43 = M_shear(3, 2); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
254 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
255 double scaling = 1.0 / (s43 * sourceZ + 1.0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
256 shearedZ = sourceZ * scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
257 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
258 a11 = s11 * scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
259 a22 = s22 * scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
260 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
261 b1 = (s13 * sourceZ + s14) * scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
262 b2 = (s23 * sourceZ + s24) * scaling; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
263 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
264 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
265 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
266 Matrix ShearWarpProjectiveTransform::CalibrateView(const Vector& camera, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
267 const Vector& principalPoint, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
268 double angle) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
269 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
270 if (camera.size() != 3 || |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
271 principalPoint.size() != 3) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
272 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
273 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
274 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
275 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
276 const double sid = boost::numeric::ublas::norm_2(camera - principalPoint); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
277 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
278 Matrix a; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
279 GeometryToolbox::AlignVectorsWithRotation(a, camera - principalPoint, |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
280 LinearAlgebra::CreateVector(0, 0, -1)); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
281 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
282 Matrix r = LinearAlgebra::Product(GeometryToolbox::CreateRotationMatrixAlongZ(angle), a); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
283 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
284 a = LinearAlgebra::ZeroMatrix(4, 4); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
285 boost::numeric::ublas::subrange(a, 0, 3, 0, 3) = r; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
286 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
287 const Vector v = LinearAlgebra::Product(r, -camera); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
288 a(0, 3) = v[0]; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
289 a(1, 3) = v[1]; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
290 a(2, 3) = v[2]; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
291 a(3, 3) = 1; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
292 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
293 Matrix perspective = LinearAlgebra::ZeroMatrix(4, 4); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
294 // https://stackoverflow.com/questions/5267866/calculation-of-a-perspective-transformation-matrix |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
295 perspective(0, 0) = sid; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
296 perspective(1, 1) = sid; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
297 perspective(2, 2) = sid; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
298 perspective(3, 2) = 1; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
299 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
300 Matrix M_view = LinearAlgebra::Product(perspective, a); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
301 assert(M_view.size1() == 4 && |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
302 M_view.size2() == 4); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
303 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
304 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
305 // Sanity checks |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
306 Vector p1 = LinearAlgebra::CreateVector(camera[0], camera[1], camera[2], 1.0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
307 Vector p2 = LinearAlgebra::CreateVector(principalPoint[0], principalPoint[1], principalPoint[2], 1.0); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
308 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
309 Vector v1 = LinearAlgebra::Product(M_view, p1); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
310 Vector v2 = LinearAlgebra::Product(M_view, p2); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
311 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
312 if (!LinearAlgebra::IsCloseToZero(v1[3]) || // Must be mapped to singularity (w=0) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
313 LinearAlgebra::IsCloseToZero(v2[3])) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
314 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
315 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
316 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
317 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
318 // The principal point must be mapped to (0,0,z,1) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
319 v2 /= v2[3]; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
320 if (!LinearAlgebra::IsCloseToZero(v2[0]) || |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
321 !LinearAlgebra::IsCloseToZero(v2[1])) |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
322 { |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
323 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
324 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
325 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
326 |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
327 return M_view; |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
328 } |
46cb2eedc2e0
ShearWarpProjectiveTransform
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
329 } |