Mercurial > hg > orthanc-stone
annotate Framework/Toolbox/LinearAlgebra.cpp @ 1164:6c159b8362ff broker
removing std::stod()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 19 Nov 2019 21:18:46 +0100 |
parents | 341e68752354 |
children | ad4e21df4e40 |
rev | line source |
---|---|
158 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
439 | 5 * Copyright (C) 2017-2019 Osimis S.A., Belgium |
158 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "LinearAlgebra.h" | |
23 | |
949
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
24 #include "../StoneException.h" |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
25 |
212
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
26 #include <Core/Logging.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
27 #include <Core/OrthancException.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
28 #include <Core/Toolbox.h> |
158 | 29 |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
30 #include <boost/lexical_cast.hpp> |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
31 #include <boost/numeric/ublas/lu.hpp> |
158 | 32 |
949
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
33 #include <stdio.h> |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
34 #include <iostream> |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
35 |
158 | 36 namespace OrthancStone |
37 { | |
38 namespace LinearAlgebra | |
39 { | |
40 void Print(const Vector& v) | |
41 { | |
42 for (size_t i = 0; i < v.size(); i++) | |
43 { | |
44 printf("%g\n", v[i]); | |
45 //printf("%8.2f\n", v[i]); | |
46 } | |
47 printf("\n"); | |
48 } | |
49 | |
50 | |
51 void Print(const Matrix& m) | |
52 { | |
53 for (size_t i = 0; i < m.size1(); i++) | |
54 { | |
55 for (size_t j = 0; j < m.size2(); j++) | |
56 { | |
57 printf("%g ", m(i,j)); | |
58 //printf("%8.2f ", m(i,j)); | |
59 } | |
60 printf("\n"); | |
61 } | |
62 printf("\n"); | |
63 } | |
64 | |
65 | |
66 bool ParseVector(Vector& target, | |
67 const std::string& value) | |
68 { | |
69 std::vector<std::string> items; | |
786
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
70 Orthanc::Toolbox::TokenizeString(items, Orthanc::Toolbox::StripSpaces(value), '\\'); |
158 | 71 |
72 target.resize(items.size()); | |
73 | |
74 for (size_t i = 0; i < items.size(); i++) | |
75 { | |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
76 /** |
1164
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
77 * SJO - 2019-11-19 - WARNING: I reverted from "std::stod()" |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
78 * to "boost::lexical_cast", as "std::stod()" is sensitive to |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
79 * locale settings, making this code non portable and very |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
80 * dangerous as it fails silently. A string such as |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
81 * "1.3671875\1.3671875" is interpreted as "1\1", because |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
82 * "std::stod()" expects a comma (",") instead of a point |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
83 * ("."). |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
84 **/ |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
85 |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
86 #if 0 // __cplusplus >= 201103L // Is C++11 enabled? |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
87 /** |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
88 * We try and avoid the use of "boost::lexical_cast<>" here, |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
89 * as it is very slow. As we are parsing many doubles, we |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
90 * prefer to use the standard "std::stod" function if |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
91 * available: http://www.cplusplus.com/reference/string/stod/ |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
92 **/ |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
93 |
158 | 94 try |
95 { | |
790
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
96 target[i] = std::stod(items[i]); |
158 | 97 } |
790
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
98 catch (std::exception&) |
158 | 99 { |
100 target.clear(); | |
101 return false; | |
102 } | |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
103 #else // Fallback implementation using Boost |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
104 try |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
105 { |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
106 target[i] = boost::lexical_cast<double>(items[i]); |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
107 } |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
108 catch (boost::bad_lexical_cast&) |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
109 { |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
110 target.clear(); |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
111 return false; |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
112 } |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
113 #endif |
158 | 114 } |
115 | |
116 return true; | |
117 } | |
118 | |
119 | |
120 bool ParseVector(Vector& target, | |
121 const Orthanc::DicomMap& dataset, | |
122 const Orthanc::DicomTag& tag) | |
123 { | |
124 std::string value; | |
994
1f74bc3459ba
fix build due to rename in Orthanc::DicomMap
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
949
diff
changeset
|
125 return (dataset.LookupStringValue(value, tag, false) && |
158 | 126 ParseVector(target, value)); |
127 } | |
128 | |
129 | |
130 void NormalizeVector(Vector& u) | |
131 { | |
132 double norm = boost::numeric::ublas::norm_2(u); | |
133 if (!IsCloseToZero(norm)) | |
134 { | |
135 u = u / norm; | |
136 } | |
137 } | |
138 | |
139 void CrossProduct(Vector& result, | |
140 const Vector& u, | |
141 const Vector& v) | |
142 { | |
143 if (u.size() != 3 || | |
144 v.size() != 3) | |
145 { | |
146 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
147 } | |
148 | |
149 result.resize(3); | |
150 | |
151 result[0] = u[1] * v[2] - u[2] * v[1]; | |
152 result[1] = u[2] * v[0] - u[0] * v[2]; | |
153 result[2] = u[0] * v[1] - u[1] * v[0]; | |
154 } | |
155 | |
1002 | 156 double DotProduct(const Vector& u, const Vector& v) |
157 { | |
158 if (u.size() != 3 || | |
159 v.size() != 3) | |
160 { | |
161 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
162 } | |
163 | |
164 return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]); | |
165 } | |
158 | 166 |
167 void FillMatrix(Matrix& target, | |
168 size_t rows, | |
169 size_t columns, | |
170 const double values[]) | |
171 { | |
172 target.resize(rows, columns); | |
173 | |
174 size_t index = 0; | |
175 | |
176 for (size_t y = 0; y < rows; y++) | |
177 { | |
178 for (size_t x = 0; x < columns; x++, index++) | |
179 { | |
180 target(y, x) = values[index]; | |
181 } | |
182 } | |
183 } | |
184 | |
185 | |
186 void FillVector(Vector& target, | |
187 size_t size, | |
188 const double values[]) | |
189 { | |
190 target.resize(size); | |
191 | |
192 for (size_t i = 0; i < size; i++) | |
193 { | |
194 target[i] = values[i]; | |
195 } | |
196 } | |
197 | |
198 | |
199 void Convert(Matrix& target, | |
200 const Vector& source) | |
201 { | |
202 const size_t n = source.size(); | |
203 | |
204 target.resize(n, 1); | |
205 | |
206 for (size_t i = 0; i < n; i++) | |
207 { | |
208 target(i, 0) = source[i]; | |
209 } | |
210 } | |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
211 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
212 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
213 double ComputeDeterminant(const Matrix& a) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
214 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
215 if (a.size1() != a.size2()) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
216 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
217 LOG(ERROR) << "Determinant only exists for square matrices"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
218 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
219 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
220 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
221 // https://en.wikipedia.org/wiki/Rule_of_Sarrus |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
222 if (a.size1() == 1) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
223 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
224 return a(0,0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
225 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
226 else if (a.size1() == 2) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
227 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
228 return a(0,0) * a(1,1) - a(0,1) * a(1,0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
229 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
230 else if (a.size1() == 3) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
231 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
232 return (a(0,0) * a(1,1) * a(2,2) + |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
233 a(0,1) * a(1,2) * a(2,0) + |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
234 a(0,2) * a(1,0) * a(2,1) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
235 a(2,0) * a(1,1) * a(0,2) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
236 a(2,1) * a(1,2) * a(0,0) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
237 a(2,2) * a(1,0) * a(0,1)); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
238 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
239 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
240 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
241 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
242 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
243 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
244 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
245 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
246 bool IsOrthogonalMatrix(const Matrix& q, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
247 double threshold) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
248 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
249 // https://en.wikipedia.org/wiki/Orthogonal_matrix |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
250 |
392 | 251 if (q.size1() != q.size2()) |
252 { | |
253 LOG(ERROR) << "An orthogonal matrix must be squared"; | |
254 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
255 } | |
256 | |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
257 using namespace boost::numeric::ublas; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
258 |
392 | 259 const Matrix check = prod(trans(q), q) - identity_matrix<double>(q.size1()); |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
260 |
160 | 261 type_traits<double>::real_type norm = norm_inf(check); |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
262 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
263 return (norm <= threshold); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
264 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
265 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
266 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
267 bool IsOrthogonalMatrix(const Matrix& q) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
268 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
269 return IsOrthogonalMatrix(q, 10.0 * std::numeric_limits<float>::epsilon()); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
270 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
271 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
272 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
273 bool IsRotationMatrix(const Matrix& r, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
274 double threshold) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
275 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
276 return (IsOrthogonalMatrix(r, threshold) && |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
277 IsNear(ComputeDeterminant(r), 1.0, threshold)); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
278 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
279 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
280 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
281 bool IsRotationMatrix(const Matrix& r) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
282 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
283 return IsRotationMatrix(r, 10.0 * std::numeric_limits<float>::epsilon()); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
284 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
285 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
286 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
287 void InvertUpperTriangularMatrix(Matrix& output, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
288 const Matrix& k) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
289 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
290 if (k.size1() != k.size2()) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
291 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
292 LOG(ERROR) << "Determinant only exists for square matrices"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
293 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
294 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
295 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
296 output.resize(k.size1(), k.size2()); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
297 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
298 for (size_t i = 1; i < k.size1(); i++) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
299 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
300 for (size_t j = 0; j < i; j++) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
301 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
302 if (!IsCloseToZero(k(i, j))) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
303 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
304 LOG(ERROR) << "Not an upper triangular matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
305 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
306 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
307 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
308 output(i, j) = 0; // The output is also upper triangular |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
309 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
310 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
311 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
312 if (k.size1() == 3) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
313 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
314 // https://math.stackexchange.com/a/1004181 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
315 double a = k(0, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
316 double b = k(0, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
317 double c = k(0, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
318 double d = k(1, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
319 double e = k(1, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
320 double f = k(2, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
321 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
322 if (IsCloseToZero(a) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
323 IsCloseToZero(d) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
324 IsCloseToZero(f)) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
325 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
326 LOG(ERROR) << "Singular upper triangular matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
327 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
328 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
329 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
330 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
331 output(0, 0) = 1.0 / a; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
332 output(0, 1) = -b / (a * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
333 output(0, 2) = (b * e - c * d) / (a * f * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
334 output(1, 1) = 1.0 / d; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
335 output(1, 2) = -e / (f * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
336 output(2, 2) = 1.0 / f; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
337 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
338 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
339 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
340 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
341 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
342 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
343 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
344 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
345 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
346 static void GetGivensComponent(double& c, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
347 double& s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
348 const Matrix& a, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
349 size_t i, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
350 size_t j) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
351 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
352 assert(i < 3 && j < 3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
353 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
354 double x = a(i, i); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
355 double y = a(i, j); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
356 double n = sqrt(x * x + y * y); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
357 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
358 if (IsCloseToZero(n)) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
359 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
360 c = 1; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
361 s = 0; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
362 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
363 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
364 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
365 c = x / n; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
366 s = -y / n; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
367 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
368 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
369 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
370 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
371 /** |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
372 * This function computes the RQ decomposition of a 3x3 matrix, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
373 * using Givens rotations. Reference: Algorithm A4.1 (page 579) of |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
374 * "Multiple View Geometry in Computer Vision" (2nd edition). The |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
375 * output matrix "Q" is a rotation matrix, and "R" is upper |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
376 * triangular. |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
377 **/ |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
378 void RQDecomposition3x3(Matrix& r, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
379 Matrix& q, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
380 const Matrix& a) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
381 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
382 using namespace boost::numeric::ublas; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
383 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
384 if (a.size1() != 3 || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
385 a.size2() != 3) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
386 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
387 LOG(ERROR) << "Only applicable to a 3x3 matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
388 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
389 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
390 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
391 r.resize(3, 3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
392 q.resize(3, 3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
393 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
394 r = a; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
395 q = identity_matrix<double>(3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
396 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
397 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
398 // Set A(2,1) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
399 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
400 GetGivensComponent(c, s, r, 2, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
401 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
402 double v[9] = { 1, 0, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
403 0, c, -s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
404 0, s, c }; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
405 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
406 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
407 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
408 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
409 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
410 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
411 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
412 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
413 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
414 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
415 // Set A(2,0) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
416 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
417 GetGivensComponent(c, s, r, 2, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
418 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
419 double v[9] = { c, 0, -s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
420 0, 1, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
421 s, 0, c }; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
422 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
423 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
424 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
425 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
426 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
427 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
428 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
429 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
430 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
431 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
432 // Set A(1,0) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
433 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
434 GetGivensComponent(c, s, r, 1, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
435 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
436 double v[9] = { c, -s, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
437 s, c, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
438 0, 0, 1 }; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
439 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
440 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
441 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
442 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
443 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
444 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
445 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
446 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
447 if (!IsCloseToZero(norm_inf(prod(r, q) - a)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
448 !IsRotationMatrix(q) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
449 !IsCloseToZero(r(1, 0)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
450 !IsCloseToZero(r(2, 0)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
451 !IsCloseToZero(r(2, 1))) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
452 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
453 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
454 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
455 } |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
456 |
169 | 457 |
458 bool InvertMatrixUnsafe(Matrix& target, | |
459 const Matrix& source) | |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
460 { |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
461 if (source.size1() != source.size2()) |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
462 { |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
463 LOG(ERROR) << "Inverse only exists for square matrices"; |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
464 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
465 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
466 |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
467 if (source.size1() < 4) |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
468 { |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
469 // For matrices with size below 4, use direct computations |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
470 // instead of LU decomposition |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
471 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
472 if (source.size1() == 0) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
473 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
474 // By convention, the inverse of the empty matrix, is itself the empty matrix |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
475 target.resize(0, 0); |
169 | 476 return true; |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
477 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
478 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
479 double determinant = ComputeDeterminant(source); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
480 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
481 if (IsCloseToZero(determinant)) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
482 { |
169 | 483 return false; |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
484 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
485 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
486 double denominator = 1.0 / determinant; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
487 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
488 target.resize(source.size1(), source.size2()); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
489 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
490 if (source.size1() == 1) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
491 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
492 target(0, 0) = denominator; |
169 | 493 |
494 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
495 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
496 else if (source.size1() == 2) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
497 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
498 // https://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_2_%C3%97_2_matrices |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
499 target(0, 0) = source(1, 1) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
500 target(0, 1) = -source(0, 1) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
501 target(1, 0) = -source(1, 0) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
502 target(1, 1) = source(0, 0) * denominator; |
169 | 503 |
504 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
505 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
506 else if (source.size1() == 3) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
507 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
508 // https://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_3_%C3%97_3_matrices |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
509 const double a = source(0, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
510 const double b = source(0, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
511 const double c = source(0, 2); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
512 const double d = source(1, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
513 const double e = source(1, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
514 const double f = source(1, 2); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
515 const double g = source(2, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
516 const double h = source(2, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
517 const double i = source(2, 2); |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
518 |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
519 target(0, 0) = (e * i - f * h) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
520 target(0, 1) = -(b * i - c * h) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
521 target(0, 2) = (b * f - c * e) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
522 target(1, 0) = -(d * i - f * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
523 target(1, 1) = (a * i - c * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
524 target(1, 2) = -(a * f - c * d) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
525 target(2, 0) = (d * h - e * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
526 target(2, 1) = -(a * h - b * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
527 target(2, 2) = (a * e - b * d) * denominator; |
169 | 528 |
529 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
530 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
531 else |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
532 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
533 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
534 } |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
535 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
536 else |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
537 { |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
538 // General case, using LU decomposition |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
539 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
540 Matrix a = source; // Copy the source matrix, as "lu_factorize()" modifies it |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
541 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
542 boost::numeric::ublas::permutation_matrix<size_t> permutation(source.size1()); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
543 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
544 if (boost::numeric::ublas::lu_factorize(a, permutation) != 0) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
545 { |
169 | 546 return false; |
547 } | |
548 else | |
549 { | |
550 target = boost::numeric::ublas::identity_matrix<double>(source.size1()); | |
551 lu_substitute(a, permutation, target); | |
552 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
553 } |
169 | 554 } |
555 } | |
556 | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
557 |
169 | 558 |
559 void InvertMatrix(Matrix& target, | |
560 const Matrix& source) | |
561 { | |
562 if (!InvertMatrixUnsafe(target, source)) | |
563 { | |
564 LOG(ERROR) << "Cannot invert singular matrix"; | |
565 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
566 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
567 } |
165
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
568 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
569 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
570 void CreateSkewSymmetric(Matrix& s, |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
571 const Vector& v) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
572 { |
392 | 573 if (v.size() != 3) |
574 { | |
575 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
576 } | |
165
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
577 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
578 s.resize(3, 3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
579 s(0,0) = 0; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
580 s(0,1) = -v[2]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
581 s(0,2) = v[1]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
582 s(1,0) = v[2]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
583 s(1,1) = 0; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
584 s(1,2) = -v[0]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
585 s(2,0) = -v[1]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
586 s(2,1) = v[0]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
587 s(2,2) = 0; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
588 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
589 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
590 |
166 | 591 Matrix InvertScalingTranslationMatrix(const Matrix& t) |
165
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
592 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
593 if (t.size1() != 4 || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
594 t.size2() != 4 || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
595 !LinearAlgebra::IsCloseToZero(t(0,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
596 !LinearAlgebra::IsCloseToZero(t(0,2)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
597 !LinearAlgebra::IsCloseToZero(t(1,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
598 !LinearAlgebra::IsCloseToZero(t(1,2)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
599 !LinearAlgebra::IsCloseToZero(t(2,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
600 !LinearAlgebra::IsCloseToZero(t(2,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
601 !LinearAlgebra::IsCloseToZero(t(3,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
602 !LinearAlgebra::IsCloseToZero(t(3,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
603 !LinearAlgebra::IsCloseToZero(t(3,2))) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
604 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
605 LOG(ERROR) << "This matrix is more than a zoom/translate transform"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
606 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
607 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
608 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
609 const double sx = t(0,0); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
610 const double sy = t(1,1); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
611 const double sz = t(2,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
612 const double w = t(3,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
613 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
614 if (LinearAlgebra::IsCloseToZero(sx) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
615 LinearAlgebra::IsCloseToZero(sy) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
616 LinearAlgebra::IsCloseToZero(sz) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
617 LinearAlgebra::IsCloseToZero(w)) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
618 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
619 LOG(ERROR) << "Singular transform"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
620 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
621 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
622 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
623 const double tx = t(0,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
624 const double ty = t(1,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
625 const double tz = t(2,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
626 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
627 Matrix m = IdentityMatrix(4); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
628 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
629 m(0,0) = 1.0 / sx; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
630 m(1,1) = 1.0 / sy; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
631 m(2,2) = 1.0 / sz; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
632 m(3,3) = 1.0 / w; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
633 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
634 m(0,3) = -tx / (sx * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
635 m(1,3) = -ty / (sy * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
636 m(2,3) = -tz / (sz * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
637 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
638 return m; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
639 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
640 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
641 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
642 bool IsShearMatrix(const Matrix& shear) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
643 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
644 return (shear.size1() == 4 && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
645 shear.size2() == 4 && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
646 LinearAlgebra::IsNear(1.0, shear(0,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
647 LinearAlgebra::IsNear(0.0, shear(0,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
648 LinearAlgebra::IsNear(0.0, shear(0,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
649 LinearAlgebra::IsNear(0.0, shear(1,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
650 LinearAlgebra::IsNear(1.0, shear(1,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
651 LinearAlgebra::IsNear(0.0, shear(1,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
652 LinearAlgebra::IsNear(0.0, shear(2,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
653 LinearAlgebra::IsNear(0.0, shear(2,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
654 LinearAlgebra::IsNear(1.0, shear(2,2)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
655 LinearAlgebra::IsNear(0.0, shear(2,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
656 LinearAlgebra::IsNear(0.0, shear(3,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
657 LinearAlgebra::IsNear(0.0, shear(3,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
658 LinearAlgebra::IsNear(1.0, shear(3,3))); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
659 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
660 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
661 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
662 Matrix InvertShearMatrix(const Matrix& shear) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
663 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
664 if (!IsShearMatrix(shear)) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
665 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
666 LOG(ERROR) << "Not a valid shear matrix"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
667 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
668 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
669 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
670 Matrix m = IdentityMatrix(4); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
671 m(0,2) = -shear(0,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
672 m(1,2) = -shear(1,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
673 m(3,2) = -shear(3,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
674 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
675 return m; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
676 } |
158 | 677 } |
949
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
678 |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
679 std::ostream& operator<<(std::ostream& s, const Vector& vec) |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
680 { |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
681 s << "("; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
682 for (size_t i = 0; i < vec.size(); ++i) |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
683 { |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
684 s << vec(i); |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
685 if (i < (vec.size() - 1)) |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
686 s << ", "; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
687 } |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
688 s << ")"; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
689 return s; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
690 } |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
691 |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
692 std::ostream& operator<<(std::ostream& s, const Matrix& m) |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
693 { |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
694 ORTHANC_ASSERT(m.size1() == m.size2()); |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
695 s << "("; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
696 for (size_t i = 0; i < m.size1(); ++i) |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
697 { |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
698 s << "("; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
699 for (size_t j = 0; j < m.size2(); ++j) |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
700 { |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
701 s << m(i,j); |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
702 if (j < (m.size2() - 1)) |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
703 s << ", "; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
704 } |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
705 s << ")"; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
706 if (i < (m.size1() - 1)) |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
707 s << ", "; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
708 } |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
709 s << ")"; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
710 return s; |
32eaf4929b08
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
Benjamin Golinvaux <bgo@osimis.io>
parents:
804
diff
changeset
|
711 } |
158 | 712 } |