Mercurial > hg > orthanc-stone
comparison Framework/Toolbox/VolumeImageGeometry.cpp @ 689:93a8949a1ef7
VolumeImageGeometry::DetectSlice()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 16 May 2019 18:33:57 +0200 |
parents | 7719eb852dd5 |
children |
comparison
equal
deleted
inserted
replaced
685:ea1a5b963798 | 689:93a8949a1ef7 |
---|---|
37 axialGeometry_.GetAxisX(), | 37 axialGeometry_.GetAxisX(), |
38 -axialGeometry_.GetNormal()); | 38 -axialGeometry_.GetNormal()); |
39 | 39 |
40 sagittalGeometry_ = CoordinateSystem3D(p, | 40 sagittalGeometry_ = CoordinateSystem3D(p, |
41 axialGeometry_.GetAxisY(), | 41 axialGeometry_.GetAxisY(), |
42 -axialGeometry_.GetNormal()); | 42 axialGeometry_.GetNormal()); |
43 | 43 |
44 Vector origin = ( | 44 Vector origin = ( |
45 axialGeometry_.MapSliceToWorldCoordinates(-0.5 * voxelDimensions_[0], | 45 axialGeometry_.MapSliceToWorldCoordinates(-0.5 * voxelDimensions_[0], |
46 -0.5 * voxelDimensions_[1]) - | 46 -0.5 * voxelDimensions_[1]) - |
47 0.5 * voxelDimensions_[2] * axialGeometry_.GetNormal()); | 47 0.5 * voxelDimensions_[2] * axialGeometry_.GetNormal()); |
114 Invalidate(); | 114 Invalidate(); |
115 } | 115 } |
116 } | 116 } |
117 | 117 |
118 | 118 |
119 const CoordinateSystem3D& VolumeImageGeometry::GetProjectionGeometry(VolumeProjection projection) const | |
120 { | |
121 switch (projection) | |
122 { | |
123 case VolumeProjection_Axial: | |
124 return axialGeometry_; | |
125 | |
126 case VolumeProjection_Coronal: | |
127 return coronalGeometry_; | |
128 | |
129 case VolumeProjection_Sagittal: | |
130 return sagittalGeometry_; | |
131 | |
132 default: | |
133 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
134 } | |
135 } | |
136 | |
137 | |
119 Vector VolumeImageGeometry::GetVoxelDimensions(VolumeProjection projection) const | 138 Vector VolumeImageGeometry::GetVoxelDimensions(VolumeProjection projection) const |
120 { | 139 { |
121 switch (projection) | 140 switch (projection) |
122 { | 141 { |
123 case VolumeProjection_Axial: | 142 case VolumeProjection_Axial: |
133 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 152 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
134 } | 153 } |
135 } | 154 } |
136 | 155 |
137 | 156 |
138 void VolumeImageGeometry::GetSliceSize(unsigned int& width, | 157 unsigned int VolumeImageGeometry::GetProjectionWidth(VolumeProjection projection) const |
139 unsigned int& height, | 158 { |
140 VolumeProjection projection) | 159 switch (projection) |
141 { | 160 { |
142 switch (projection) | 161 case VolumeProjection_Axial: |
143 { | 162 return width_; |
144 case VolumeProjection_Axial: | 163 |
145 width = width_; | 164 case VolumeProjection_Coronal: |
146 height = height_; | 165 return width_; |
147 break; | 166 |
148 | 167 case VolumeProjection_Sagittal: |
149 case VolumeProjection_Coronal: | 168 return height_; |
150 width = width_; | 169 |
151 height = depth_; | 170 default: |
152 break; | 171 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
153 | 172 } |
154 case VolumeProjection_Sagittal: | 173 } |
155 width = height_; | 174 |
156 height = depth_; | 175 |
157 break; | 176 unsigned int VolumeImageGeometry::GetProjectionHeight(VolumeProjection projection) const |
158 | 177 { |
159 default: | 178 switch (projection) |
160 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 179 { |
161 } | 180 case VolumeProjection_Axial: |
162 } | 181 return height_; |
163 | 182 |
183 case VolumeProjection_Coronal: | |
184 return depth_; | |
185 | |
186 case VolumeProjection_Sagittal: | |
187 return depth_; | |
188 | |
189 default: | |
190 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
191 } | |
192 } | |
193 | |
194 | |
195 unsigned int VolumeImageGeometry::GetProjectionDepth(VolumeProjection projection) const | |
196 { | |
197 switch (projection) | |
198 { | |
199 case VolumeProjection_Axial: | |
200 return depth_; | |
201 | |
202 case VolumeProjection_Coronal: | |
203 return height_; | |
204 | |
205 case VolumeProjection_Sagittal: | |
206 return width_; | |
207 | |
208 default: | |
209 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
210 } | |
211 } | |
164 | 212 |
165 | 213 |
166 Vector VolumeImageGeometry::GetCoordinates(float x, | 214 Vector VolumeImageGeometry::GetCoordinates(float x, |
167 float y, | 215 float y, |
168 float z) const | 216 float z) const |
175 return LinearAlgebra::CreateVector(p[0], p[1], p[2]); | 223 return LinearAlgebra::CreateVector(p[0], p[1], p[2]); |
176 } | 224 } |
177 | 225 |
178 | 226 |
179 bool VolumeImageGeometry::DetectProjection(VolumeProjection& projection, | 227 bool VolumeImageGeometry::DetectProjection(VolumeProjection& projection, |
180 const CoordinateSystem3D& plane) const | 228 const Vector& planeNormal) const |
181 { | 229 { |
182 if (GeometryToolbox::IsParallel(plane.GetNormal(), | 230 if (GeometryToolbox::IsParallel(planeNormal, axialGeometry_.GetNormal())) |
183 axialGeometry_.GetNormal())) | |
184 { | 231 { |
185 projection = VolumeProjection_Axial; | 232 projection = VolumeProjection_Axial; |
186 return true; | 233 return true; |
187 } | 234 } |
188 else if (GeometryToolbox::IsParallel(plane.GetNormal(), | 235 else if (GeometryToolbox::IsParallel(planeNormal, coronalGeometry_.GetNormal())) |
189 coronalGeometry_.GetNormal())) | |
190 { | 236 { |
191 projection = VolumeProjection_Coronal; | 237 projection = VolumeProjection_Coronal; |
192 return true; | 238 return true; |
193 } | 239 } |
194 else if (GeometryToolbox::IsParallel(plane.GetNormal(), | 240 else if (GeometryToolbox::IsParallel(planeNormal, sagittalGeometry_.GetNormal())) |
195 sagittalGeometry_.GetNormal())) | |
196 { | 241 { |
197 projection = VolumeProjection_Sagittal; | 242 projection = VolumeProjection_Sagittal; |
198 return true; | 243 return true; |
199 } | 244 } |
200 else | 245 else |
201 { | 246 { |
202 return false; | 247 return false; |
203 } | 248 } |
204 } | 249 } |
250 | |
251 | |
252 bool VolumeImageGeometry::DetectSlice(VolumeProjection& projection, | |
253 unsigned int& slice, | |
254 const CoordinateSystem3D& plane) const | |
255 { | |
256 if (!DetectProjection(projection, plane.GetNormal())) | |
257 { | |
258 return false; | |
259 } | |
260 | |
261 // Transforms the coordinates of the origin of the plane, into the | |
262 // coordinates of the axial geometry | |
263 const Vector& origin = plane.GetOrigin(); | |
264 Vector p = LinearAlgebra::Product( | |
265 transformInverse_, | |
266 LinearAlgebra::CreateVector(origin[0], origin[1], origin[2], 1)); | |
267 | |
268 assert(LinearAlgebra::IsNear(p[3], 1)); | |
269 | |
270 double z; | |
271 | |
272 switch (projection) | |
273 { | |
274 case VolumeProjection_Axial: | |
275 z = p[2]; | |
276 break; | |
277 | |
278 case VolumeProjection_Coronal: | |
279 z = p[1]; | |
280 break; | |
281 | |
282 case VolumeProjection_Sagittal: | |
283 z = p[0]; | |
284 break; | |
285 | |
286 default: | |
287 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
288 } | |
289 | |
290 const unsigned int projectionDepth = GetProjectionDepth(projection); | |
291 | |
292 z *= static_cast<double>(projectionDepth); | |
293 if (z < 0) | |
294 { | |
295 return false; | |
296 } | |
297 | |
298 unsigned int d = static_cast<unsigned int>(std::floor(z)); | |
299 if (d >= projectionDepth) | |
300 { | |
301 return false; | |
302 } | |
303 else | |
304 { | |
305 slice = d; | |
306 return true; | |
307 } | |
308 } | |
205 } | 309 } |