Mercurial > hg > orthanc-stone
annotate OrthancStone/Sources/Toolbox/LinearAlgebra.cpp @ 1615:f5d4bd7b5593
new class: OsiriXLayerFactory
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 30 Oct 2020 17:26:44 +0100 |
parents | 8563ea5d8ae4 |
children | 1a714e21ea7c |
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 | |
1270
2d8ab34c8c91
upgrade to year 2020
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium |
158 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public License |
158 | 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 | |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
15 * Lesser General Public License for more details. |
1596
4fb8fdf03314
removed annoying whitespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1512
diff
changeset
|
16 * |
1598
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
18 * License along with this program. If not, see |
8563ea5d8ae4
relicensing some files, cf. osimis bm26 and chu agreement on 2020-05-20
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1596
diff
changeset
|
19 * <http://www.gnu.org/licenses/>. |
158 | 20 **/ |
21 | |
22 | |
23 #include "LinearAlgebra.h" | |
24 | |
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
|
25 #include "../StoneException.h" |
1170
1644de437a7b
fixes related to swapped normal in sagittal geometry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1167
diff
changeset
|
26 #include "GenericToolbox.h" |
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
|
27 |
1455
30deba7bc8e2
simplifying include_directories
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1279
diff
changeset
|
28 #include <Logging.h> |
30deba7bc8e2
simplifying include_directories
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1279
diff
changeset
|
29 #include <OrthancException.h> |
30deba7bc8e2
simplifying include_directories
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1279
diff
changeset
|
30 #include <Toolbox.h> |
158 | 31 |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
32 #include <boost/lexical_cast.hpp> |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
33 #include <boost/numeric/ublas/lu.hpp> |
158 | 34 |
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
|
35 #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
|
36 #include <iostream> |
1167
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
37 #include <cstdlib> |
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
|
38 |
158 | 39 namespace OrthancStone |
40 { | |
41 namespace LinearAlgebra | |
42 { | |
43 void Print(const Vector& v) | |
44 { | |
45 for (size_t i = 0; i < v.size(); i++) | |
46 { | |
47 printf("%g\n", v[i]); | |
48 //printf("%8.2f\n", v[i]); | |
49 } | |
50 printf("\n"); | |
51 } | |
52 | |
53 | |
54 void Print(const Matrix& m) | |
55 { | |
56 for (size_t i = 0; i < m.size1(); i++) | |
57 { | |
58 for (size_t j = 0; j < m.size2(); j++) | |
59 { | |
60 printf("%g ", m(i,j)); | |
61 //printf("%8.2f ", m(i,j)); | |
62 } | |
63 printf("\n"); | |
64 } | |
65 printf("\n"); | |
66 } | |
67 | |
68 | |
69 bool ParseVector(Vector& target, | |
70 const std::string& value) | |
71 { | |
72 std::vector<std::string> items; | |
786
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
73 Orthanc::Toolbox::TokenizeString(items, Orthanc::Toolbox::StripSpaces(value), '\\'); |
158 | 74 |
75 target.resize(items.size()); | |
76 | |
77 for (size_t i = 0; i < items.size(); i++) | |
78 { | |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
79 /** |
1164
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
80 * SJO - 2019-11-19 - WARNING: I reverted from "std::stod()" |
1167
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
81 * to "boost::lexical_cast", as both "std::stod()" and |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
82 * "std::strtod()" are sensitive to locale settings, making |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
83 * this code non portable and very dangerous as it fails |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
84 * silently. A string such as "1.3671875\1.3671875" is |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
85 * interpreted as "1\1", because "std::stod()" expects a comma |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
86 * (",") instead of a point ("."). This problem is notably |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
87 * seen in Qt-based applications, that somehow set locales |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
88 * aggressively. |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
89 * |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
90 * "boost::lexical_cast<>" is also dependent on the locale |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
91 * settings, but apparently not in a way that makes this |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
92 * function fail with Qt. The Orthanc core defines macro |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
93 * "-DBOOST_LEXICAL_CAST_ASSUME_C_LOCALE" in static builds to |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
94 * this end. |
1164
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
95 **/ |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
96 |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
97 #if 0 // __cplusplus >= 201103L // Is C++11 enabled? |
6c159b8362ff
removing std::stod()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1002
diff
changeset
|
98 /** |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
99 * We try and avoid the use of "boost::lexical_cast<>" here, |
1167
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
100 * as it is very slow, and as Stone has to parse many doubles. |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
101 * https://tinodidriksen.com/2011/05/cpp-convert-string-to-double-speed/ |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
102 **/ |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
103 |
158 | 104 try |
105 { | |
790
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
106 target[i] = std::stod(items[i]); |
158 | 107 } |
790
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
108 catch (std::exception&) |
158 | 109 { |
110 target.clear(); | |
111 return false; | |
112 } | |
1167
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
113 |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
114 #elif 0 |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
115 /** |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
116 * "std::strtod()" is the recommended alternative to |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
117 * "std::stod()". It is apparently as fast as plain-C |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
118 * "atof()", with more security. |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
119 **/ |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
120 char* end = NULL; |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
121 target[i] = std::strtod(items[i].c_str(), &end); |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
122 if (end == NULL || |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
123 end != items[i].c_str() + items[i].size()) |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
124 { |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
125 return false; |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
126 } |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
127 |
1170
1644de437a7b
fixes related to swapped normal in sagittal geometry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1167
diff
changeset
|
128 #elif 1 |
1175 | 129 /** |
130 * Use of our homemade implementation of | |
131 * "boost::lexical_cast<double>()". It is much faster than boost. | |
132 **/ | |
1170
1644de437a7b
fixes related to swapped normal in sagittal geometry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1167
diff
changeset
|
133 if (!GenericToolbox::StringToDouble(target[i], items[i].c_str())) |
1644de437a7b
fixes related to swapped normal in sagittal geometry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1167
diff
changeset
|
134 { |
1644de437a7b
fixes related to swapped normal in sagittal geometry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1167
diff
changeset
|
135 return false; |
1644de437a7b
fixes related to swapped normal in sagittal geometry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1167
diff
changeset
|
136 } |
1644de437a7b
fixes related to swapped normal in sagittal geometry
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1167
diff
changeset
|
137 |
1167
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
138 #else |
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
139 /** |
1175 | 140 * Fallback implementation using Boost (slower, but somehow |
141 * independent to locale contrarily to "std::stod()", and | |
142 * generic as it does not use our custom implementation). | |
1167
ad4e21df4e40
enriching OrthancStone::StoneInitialize()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1164
diff
changeset
|
143 **/ |
804
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
144 try |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
145 { |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
146 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
|
147 } |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
148 catch (boost::bad_lexical_cast&) |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
149 { |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
150 target.clear(); |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
151 return false; |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
152 } |
61ba4b504e9a
PolylineSceneLayer now has one color per chain
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
790
diff
changeset
|
153 #endif |
158 | 154 } |
155 | |
156 return true; | |
157 } | |
158 | |
159 | |
160 bool ParseVector(Vector& target, | |
161 const Orthanc::DicomMap& dataset, | |
162 const Orthanc::DicomTag& tag) | |
163 { | |
164 std::string value; | |
994
1f74bc3459ba
fix build due to rename in Orthanc::DicomMap
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
949
diff
changeset
|
165 return (dataset.LookupStringValue(value, tag, false) && |
158 | 166 ParseVector(target, value)); |
167 } | |
168 | |
169 | |
170 void NormalizeVector(Vector& u) | |
171 { | |
172 double norm = boost::numeric::ublas::norm_2(u); | |
173 if (!IsCloseToZero(norm)) | |
174 { | |
175 u = u / norm; | |
176 } | |
177 } | |
178 | |
179 void CrossProduct(Vector& result, | |
180 const Vector& u, | |
181 const Vector& v) | |
182 { | |
183 if (u.size() != 3 || | |
184 v.size() != 3) | |
185 { | |
186 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
187 } | |
188 | |
189 result.resize(3); | |
190 | |
191 result[0] = u[1] * v[2] - u[2] * v[1]; | |
192 result[1] = u[2] * v[0] - u[0] * v[2]; | |
193 result[2] = u[0] * v[1] - u[1] * v[0]; | |
194 } | |
195 | |
1002 | 196 double DotProduct(const Vector& u, const Vector& v) |
197 { | |
198 if (u.size() != 3 || | |
1477
5732edec7cbd
sorting frames in 3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1455
diff
changeset
|
199 v.size() != 3) |
1002 | 200 { |
201 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
202 } | |
203 | |
204 return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]); | |
205 } | |
158 | 206 |
207 void FillMatrix(Matrix& target, | |
208 size_t rows, | |
209 size_t columns, | |
210 const double values[]) | |
211 { | |
212 target.resize(rows, columns); | |
213 | |
214 size_t index = 0; | |
215 | |
216 for (size_t y = 0; y < rows; y++) | |
217 { | |
218 for (size_t x = 0; x < columns; x++, index++) | |
219 { | |
220 target(y, x) = values[index]; | |
221 } | |
222 } | |
223 } | |
224 | |
225 | |
226 void FillVector(Vector& target, | |
227 size_t size, | |
228 const double values[]) | |
229 { | |
230 target.resize(size); | |
231 | |
232 for (size_t i = 0; i < size; i++) | |
233 { | |
234 target[i] = values[i]; | |
235 } | |
236 } | |
237 | |
238 | |
239 void Convert(Matrix& target, | |
240 const Vector& source) | |
241 { | |
242 const size_t n = source.size(); | |
243 | |
244 target.resize(n, 1); | |
245 | |
246 for (size_t i = 0; i < n; i++) | |
247 { | |
248 target(i, 0) = source[i]; | |
249 } | |
250 } | |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
251 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
252 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
253 double ComputeDeterminant(const Matrix& a) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
254 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
255 if (a.size1() != a.size2()) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
256 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
257 LOG(ERROR) << "Determinant only exists for square matrices"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
258 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
259 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
260 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
261 // https://en.wikipedia.org/wiki/Rule_of_Sarrus |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
262 if (a.size1() == 1) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
263 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
264 return a(0,0); |
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 else if (a.size1() == 2) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
267 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
268 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
|
269 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
270 else if (a.size1() == 3) |
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 return (a(0,0) * a(1,1) * a(2,2) + |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
273 a(0,1) * a(1,2) * a(2,0) + |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
274 a(0,2) * a(1,0) * a(2,1) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
275 a(2,0) * a(1,1) * a(0,2) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
276 a(2,1) * a(1,2) * a(0,0) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
277 a(2,2) * a(1,0) * a(0,1)); |
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 else |
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 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
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 } |
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 bool IsOrthogonalMatrix(const Matrix& q, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
287 double threshold) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
288 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
289 // https://en.wikipedia.org/wiki/Orthogonal_matrix |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
290 |
392 | 291 if (q.size1() != q.size2()) |
292 { | |
293 LOG(ERROR) << "An orthogonal matrix must be squared"; | |
294 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
295 } | |
296 | |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
297 using namespace boost::numeric::ublas; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
298 |
392 | 299 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
|
300 |
160 | 301 type_traits<double>::real_type norm = norm_inf(check); |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
302 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
303 return (norm <= threshold); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
304 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
305 |
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 bool IsOrthogonalMatrix(const Matrix& q) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
308 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
309 return IsOrthogonalMatrix(q, 10.0 * std::numeric_limits<float>::epsilon()); |
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 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
313 bool IsRotationMatrix(const Matrix& r, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
314 double threshold) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
315 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
316 return (IsOrthogonalMatrix(r, threshold) && |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
317 IsNear(ComputeDeterminant(r), 1.0, threshold)); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
318 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
319 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
320 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
321 bool IsRotationMatrix(const Matrix& r) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
322 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
323 return IsRotationMatrix(r, 10.0 * std::numeric_limits<float>::epsilon()); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
324 } |
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 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
327 void InvertUpperTriangularMatrix(Matrix& output, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
328 const Matrix& k) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
329 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
330 if (k.size1() != k.size2()) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
331 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
332 LOG(ERROR) << "Determinant only exists for square matrices"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
333 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
334 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
335 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
336 output.resize(k.size1(), k.size2()); |
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 for (size_t i = 1; i < k.size1(); i++) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
339 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
340 for (size_t j = 0; j < i; j++) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
341 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
342 if (!IsCloseToZero(k(i, j))) |
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 LOG(ERROR) << "Not an upper triangular matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
345 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
346 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
347 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
348 output(i, j) = 0; // The output is also upper triangular |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
349 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
350 } |
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 if (k.size1() == 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 // https://math.stackexchange.com/a/1004181 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
355 double a = k(0, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
356 double b = k(0, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
357 double c = k(0, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
358 double d = k(1, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
359 double e = k(1, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
360 double f = k(2, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
361 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
362 if (IsCloseToZero(a) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
363 IsCloseToZero(d) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
364 IsCloseToZero(f)) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
365 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
366 LOG(ERROR) << "Singular upper triangular matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
367 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
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 else |
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 output(0, 0) = 1.0 / a; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
372 output(0, 1) = -b / (a * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
373 output(0, 2) = (b * e - c * d) / (a * f * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
374 output(1, 1) = 1.0 / d; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
375 output(1, 2) = -e / (f * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
376 output(2, 2) = 1.0 / f; |
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 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
379 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
380 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
381 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
382 } |
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 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
385 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
386 static void GetGivensComponent(double& c, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
387 double& s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
388 const Matrix& a, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
389 size_t i, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
390 size_t j) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
391 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
392 assert(i < 3 && j < 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 double x = a(i, i); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
395 double y = a(i, j); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
396 double n = sqrt(x * x + y * y); |
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 if (IsCloseToZero(n)) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
399 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
400 c = 1; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
401 s = 0; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
402 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
403 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
404 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
405 c = x / n; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
406 s = -y / n; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
407 } |
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 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
410 |
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 * This function computes the RQ decomposition of a 3x3 matrix, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
413 * using Givens rotations. Reference: Algorithm A4.1 (page 579) of |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
414 * "Multiple View Geometry in Computer Vision" (2nd edition). The |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
415 * output matrix "Q" is a rotation matrix, and "R" is upper |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
416 * triangular. |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
417 **/ |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
418 void RQDecomposition3x3(Matrix& r, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
419 Matrix& q, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
420 const Matrix& a) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
421 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
422 using namespace boost::numeric::ublas; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
423 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
424 if (a.size1() != 3 || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
425 a.size2() != 3) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
426 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
427 LOG(ERROR) << "Only applicable to a 3x3 matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
428 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
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 r.resize(3, 3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
432 q.resize(3, 3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
433 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
434 r = a; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
435 q = identity_matrix<double>(3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
436 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
437 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
438 // Set A(2,1) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
439 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
440 GetGivensComponent(c, s, r, 2, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
441 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
442 double v[9] = { 1, 0, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
443 0, c, -s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
444 0, s, c }; |
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 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
447 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
448 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
449 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
450 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
451 } |
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 |
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 // Set A(2,0) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
456 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
457 GetGivensComponent(c, s, r, 2, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
458 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
459 double v[9] = { c, 0, -s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
460 0, 1, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
461 s, 0, c }; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
462 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
463 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
464 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
465 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
466 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
467 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
468 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
469 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
470 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
471 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
472 // Set A(1,0) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
473 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
474 GetGivensComponent(c, s, r, 1, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
475 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
476 double v[9] = { c, -s, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
477 s, c, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
478 0, 0, 1 }; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
479 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
480 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
481 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
482 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
483 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
484 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
485 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
486 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
487 if (!IsCloseToZero(norm_inf(prod(r, q) - a)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
488 !IsRotationMatrix(q) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
489 !IsCloseToZero(r(1, 0)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
490 !IsCloseToZero(r(2, 0)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
491 !IsCloseToZero(r(2, 1))) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
492 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
493 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
494 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
495 } |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
496 |
169 | 497 |
498 bool InvertMatrixUnsafe(Matrix& target, | |
499 const Matrix& source) | |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
500 { |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
501 if (source.size1() != source.size2()) |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
502 { |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
503 LOG(ERROR) << "Inverse only exists for square matrices"; |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
504 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
505 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
506 |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
507 if (source.size1() < 4) |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
508 { |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
509 // For matrices with size below 4, use direct computations |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
510 // instead of LU decomposition |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
511 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
512 if (source.size1() == 0) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
513 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
514 // 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
|
515 target.resize(0, 0); |
169 | 516 return true; |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
517 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
518 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
519 double determinant = ComputeDeterminant(source); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
520 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
521 if (IsCloseToZero(determinant)) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
522 { |
169 | 523 return false; |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
524 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
525 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
526 double denominator = 1.0 / determinant; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
527 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
528 target.resize(source.size1(), source.size2()); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
529 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
530 if (source.size1() == 1) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
531 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
532 target(0, 0) = denominator; |
169 | 533 |
534 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
535 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
536 else if (source.size1() == 2) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
537 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
538 // 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
|
539 target(0, 0) = source(1, 1) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
540 target(0, 1) = -source(0, 1) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
541 target(1, 0) = -source(1, 0) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
542 target(1, 1) = source(0, 0) * denominator; |
169 | 543 |
544 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
545 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
546 else if (source.size1() == 3) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
547 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
548 // 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
|
549 const double a = source(0, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
550 const double b = source(0, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
551 const double c = source(0, 2); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
552 const double d = source(1, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
553 const double e = source(1, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
554 const double f = source(1, 2); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
555 const double g = source(2, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
556 const double h = source(2, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
557 const double i = source(2, 2); |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
558 |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
559 target(0, 0) = (e * i - f * h) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
560 target(0, 1) = -(b * i - c * h) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
561 target(0, 2) = (b * f - c * e) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
562 target(1, 0) = -(d * i - f * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
563 target(1, 1) = (a * i - c * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
564 target(1, 2) = -(a * f - c * d) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
565 target(2, 0) = (d * h - e * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
566 target(2, 1) = -(a * h - b * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
567 target(2, 2) = (a * e - b * d) * denominator; |
169 | 568 |
569 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
570 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
571 else |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
572 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
573 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
574 } |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
575 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
576 else |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
577 { |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
578 // General case, using LU decomposition |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
579 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
580 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
|
581 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
582 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
|
583 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
584 if (boost::numeric::ublas::lu_factorize(a, permutation) != 0) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
585 { |
169 | 586 return false; |
587 } | |
588 else | |
589 { | |
590 target = boost::numeric::ublas::identity_matrix<double>(source.size1()); | |
591 lu_substitute(a, permutation, target); | |
592 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
593 } |
169 | 594 } |
595 } | |
596 | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
597 |
169 | 598 |
599 void InvertMatrix(Matrix& target, | |
600 const Matrix& source) | |
601 { | |
602 if (!InvertMatrixUnsafe(target, source)) | |
603 { | |
604 LOG(ERROR) << "Cannot invert singular matrix"; | |
605 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
606 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
607 } |
165
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 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
610 void CreateSkewSymmetric(Matrix& s, |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
611 const Vector& v) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
612 { |
392 | 613 if (v.size() != 3) |
614 { | |
615 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
616 } | |
165
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
617 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
618 s.resize(3, 3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
619 s(0,0) = 0; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
620 s(0,1) = -v[2]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
621 s(0,2) = v[1]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
622 s(1,0) = v[2]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
623 s(1,1) = 0; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
624 s(1,2) = -v[0]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
625 s(2,0) = -v[1]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
626 s(2,1) = v[0]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
627 s(2,2) = 0; |
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 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
630 |
166 | 631 Matrix InvertScalingTranslationMatrix(const Matrix& t) |
165
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
632 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
633 if (t.size1() != 4 || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
634 t.size2() != 4 || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
635 !LinearAlgebra::IsCloseToZero(t(0,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
636 !LinearAlgebra::IsCloseToZero(t(0,2)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
637 !LinearAlgebra::IsCloseToZero(t(1,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
638 !LinearAlgebra::IsCloseToZero(t(1,2)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
639 !LinearAlgebra::IsCloseToZero(t(2,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
640 !LinearAlgebra::IsCloseToZero(t(2,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
641 !LinearAlgebra::IsCloseToZero(t(3,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
642 !LinearAlgebra::IsCloseToZero(t(3,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
643 !LinearAlgebra::IsCloseToZero(t(3,2))) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
644 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
645 LOG(ERROR) << "This matrix is more than a zoom/translate transform"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
646 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
647 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
648 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
649 const double sx = t(0,0); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
650 const double sy = t(1,1); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
651 const double sz = t(2,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
652 const double w = t(3,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
653 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
654 if (LinearAlgebra::IsCloseToZero(sx) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
655 LinearAlgebra::IsCloseToZero(sy) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
656 LinearAlgebra::IsCloseToZero(sz) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
657 LinearAlgebra::IsCloseToZero(w)) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
658 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
659 LOG(ERROR) << "Singular transform"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
660 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
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 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
663 const double tx = t(0,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
664 const double ty = t(1,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
665 const double tz = t(2,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
666 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
667 Matrix m = IdentityMatrix(4); |
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 m(0,0) = 1.0 / sx; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
670 m(1,1) = 1.0 / sy; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
671 m(2,2) = 1.0 / sz; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
672 m(3,3) = 1.0 / w; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
673 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
674 m(0,3) = -tx / (sx * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
675 m(1,3) = -ty / (sy * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
676 m(2,3) = -tz / (sz * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
677 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
678 return m; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
679 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
680 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
681 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
682 bool IsShearMatrix(const Matrix& shear) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
683 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
684 return (shear.size1() == 4 && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
685 shear.size2() == 4 && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
686 LinearAlgebra::IsNear(1.0, shear(0,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
687 LinearAlgebra::IsNear(0.0, shear(0,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
688 LinearAlgebra::IsNear(0.0, shear(0,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
689 LinearAlgebra::IsNear(0.0, shear(1,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
690 LinearAlgebra::IsNear(1.0, shear(1,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
691 LinearAlgebra::IsNear(0.0, shear(1,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
692 LinearAlgebra::IsNear(0.0, shear(2,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
693 LinearAlgebra::IsNear(0.0, shear(2,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
694 LinearAlgebra::IsNear(1.0, shear(2,2)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
695 LinearAlgebra::IsNear(0.0, shear(2,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
696 LinearAlgebra::IsNear(0.0, shear(3,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
697 LinearAlgebra::IsNear(0.0, shear(3,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
698 LinearAlgebra::IsNear(1.0, shear(3,3))); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
699 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
700 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
701 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
702 Matrix InvertShearMatrix(const Matrix& shear) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
703 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
704 if (!IsShearMatrix(shear)) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
705 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
706 LOG(ERROR) << "Not a valid shear matrix"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
707 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
708 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
709 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
710 Matrix m = IdentityMatrix(4); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
711 m(0,2) = -shear(0,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
712 m(1,2) = -shear(1,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
713 m(3,2) = -shear(3,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
714 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
715 return m; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
716 } |
158 | 717 } |
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
|
718 |
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
|
719 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
|
720 { |
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
|
721 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
|
722 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
|
723 { |
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
|
724 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
|
725 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
|
726 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
|
727 } |
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
|
728 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
|
729 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
|
730 } |
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
|
731 |
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
|
732 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
|
733 { |
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
|
734 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
|
735 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
|
736 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
|
737 { |
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
|
738 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
|
739 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
|
740 { |
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
|
741 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
|
742 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
|
743 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
|
744 } |
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
|
745 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
|
746 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
|
747 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
|
748 } |
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
|
749 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
|
750 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
|
751 } |
158 | 752 } |