Mercurial > hg > orthanc-stone
comparison Framework/Volumes/VolumeReslicer.cpp @ 179:db21c1810c89 wasm
moving PixelTraits to the Orthanc core
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 13 Mar 2018 17:42:49 +0100 |
parents | 83200c4d07ca |
children | 4da803580da9 |
comparison
equal
deleted
inserted
replaced
178:6dafcdec4b87 | 179:db21c1810c89 |
---|---|
1 #include "VolumeReslicer.h" | 1 #include "VolumeReslicer.h" |
2 | 2 |
3 #include "../Toolbox/GeometryToolbox.h" | 3 #include "../Toolbox/GeometryToolbox.h" |
4 | 4 |
5 #include <Core/Images/ImageTraits.h> | |
5 #include <Core/Logging.h> | 6 #include <Core/Logging.h> |
6 #include <Core/OrthancException.h> | 7 #include <Core/OrthancException.h> |
7 | 8 |
8 #include <boost/math/special_functions/round.hpp> | 9 #include <boost/math/special_functions/round.hpp> |
9 | 10 |
26 TransferFunction_Copy, | 27 TransferFunction_Copy, |
27 TransferFunction_Float, | 28 TransferFunction_Float, |
28 TransferFunction_Linear | 29 TransferFunction_Linear |
29 }; | 30 }; |
30 | 31 |
31 | |
32 template <Orthanc::PixelFormat Format> | |
33 struct PixelTraits; | |
34 | |
35 template <> | |
36 struct PixelTraits<Orthanc::PixelFormat_Grayscale8> | |
37 { | |
38 typedef uint8_t PixelType; | |
39 | |
40 static void SetOutOfVolume(PixelType& target) | |
41 { | |
42 target = 0; | |
43 } | |
44 | |
45 static void GetVoxel(PixelType& target, | |
46 const ImageBuffer3D& image, | |
47 unsigned int x, | |
48 unsigned int y, | |
49 unsigned int z) | |
50 { | |
51 assert(x < image.GetWidth() && y < image.GetHeight() && z < image.GetDepth()); | |
52 target = image.GetVoxelGrayscale8Unchecked(x, y, z); | |
53 } | |
54 | |
55 static float GetFloatVoxel(const ImageBuffer3D& image, | |
56 unsigned int x, | |
57 unsigned int y, | |
58 unsigned int z) | |
59 { | |
60 assert(x < image.GetWidth() && y < image.GetHeight() && z < image.GetDepth()); | |
61 return static_cast<float>(image.GetVoxelGrayscale8Unchecked(x, y, z)); | |
62 } | |
63 }; | |
64 | |
65 template <> | |
66 struct PixelTraits<Orthanc::PixelFormat_Grayscale16> | |
67 { | |
68 typedef uint16_t PixelType; | |
69 | |
70 static void SetOutOfVolume(PixelType& target) | |
71 { | |
72 target = 0; | |
73 } | |
74 | |
75 static void GetVoxel(PixelType& target, | |
76 const ImageBuffer3D& image, | |
77 unsigned int x, | |
78 unsigned int y, | |
79 unsigned int z) | |
80 { | |
81 assert(x < image.GetWidth() && y < image.GetHeight() && z < image.GetDepth()); | |
82 target = image.GetVoxelGrayscale16Unchecked(x, y, z); | |
83 } | |
84 | |
85 static float GetFloatVoxel(const ImageBuffer3D& image, | |
86 unsigned int x, | |
87 unsigned int y, | |
88 unsigned int z) | |
89 { | |
90 assert(x < image.GetWidth() && y < image.GetHeight() && z < image.GetDepth()); | |
91 return static_cast<float>(image.GetVoxelGrayscale16Unchecked(x, y, z)); | |
92 } | |
93 }; | |
94 | |
95 | |
96 template <> | |
97 struct PixelTraits<Orthanc::PixelFormat_SignedGrayscale16> | |
98 { | |
99 typedef int16_t PixelType; | |
100 | |
101 static void SetOutOfVolume(PixelType& target) | |
102 { | |
103 target = std::numeric_limits<PixelType>::min(); | |
104 } | |
105 | |
106 static void GetVoxel(PixelType& target, | |
107 const ImageBuffer3D& image, | |
108 unsigned int x, | |
109 unsigned int y, | |
110 unsigned int z) | |
111 { | |
112 assert(x < image.GetWidth() && y < image.GetHeight() && z < image.GetDepth()); | |
113 target = image.GetVoxelSignedGrayscale16Unchecked(x, y, z); | |
114 } | |
115 | |
116 static float GetFloatVoxel(const ImageBuffer3D& image, | |
117 unsigned int x, | |
118 unsigned int y, | |
119 unsigned int z) | |
120 { | |
121 assert(x < image.GetWidth() && y < image.GetHeight() && z < image.GetDepth()); | |
122 return static_cast<float>(image.GetVoxelSignedGrayscale16Unchecked(x, y, z)); | |
123 } | |
124 }; | |
125 | |
126 | |
127 template <> | |
128 struct PixelTraits<Orthanc::PixelFormat_BGRA32> | |
129 { | |
130 struct PixelType | |
131 { | |
132 uint8_t blue_; | |
133 uint8_t green_; | |
134 uint8_t red_; | |
135 uint8_t alpha_; | |
136 }; | |
137 }; | |
138 | |
139 | |
140 | |
141 template <Orthanc::PixelFormat InputFormat, | 32 template <Orthanc::PixelFormat InputFormat, |
142 Orthanc::PixelFormat OutputFormat> | 33 Orthanc::PixelFormat OutputFormat> |
143 class PixelWriter | 34 class PixelWriter |
144 { | 35 { |
145 public: | 36 public: |
146 typedef typename PixelTraits<InputFormat>::PixelType InputPixelType; | 37 typedef typename Orthanc::PixelTraits<InputFormat>::PixelType InputPixelType; |
147 typedef PixelTraits<OutputFormat> OutputPixelTraits; | 38 typedef Orthanc::PixelTraits<OutputFormat> OutputPixelTraits; |
148 typedef typename PixelTraits<OutputFormat>::PixelType OutputPixelType; | 39 typedef typename Orthanc::PixelTraits<OutputFormat>::PixelType OutputPixelType; |
149 | 40 |
150 private: | 41 private: |
151 template <typename T> | 42 template <typename T> |
152 static void SetValueInternal(OutputPixelType* pixel, | 43 static void SetValueInternal(OutputPixelType* pixel, |
153 const T& value) | 44 const T& value) |
185 | 76 |
186 template <Orthanc::PixelFormat InputFormat> | 77 template <Orthanc::PixelFormat InputFormat> |
187 class PixelWriter<InputFormat, Orthanc::PixelFormat_BGRA32> | 78 class PixelWriter<InputFormat, Orthanc::PixelFormat_BGRA32> |
188 { | 79 { |
189 public: | 80 public: |
190 typedef typename PixelTraits<InputFormat>::PixelType InputPixelType; | 81 typedef typename Orthanc::PixelTraits<InputFormat>::PixelType InputPixelType; |
191 typedef PixelTraits<Orthanc::PixelFormat_BGRA32> OutputPixelTraits; | 82 typedef Orthanc::PixelTraits<Orthanc::PixelFormat_BGRA32> OutputPixelTraits; |
192 typedef PixelTraits<Orthanc::PixelFormat_BGRA32>::PixelType OutputPixelType; | 83 typedef Orthanc::PixelTraits<Orthanc::PixelFormat_BGRA32>::PixelType OutputPixelType; |
193 | 84 |
194 private: | 85 private: |
195 template <typename T> | 86 template <typename T> |
196 static void SetValueInternal(OutputPixelType* pixel, | 87 static void SetValueInternal(OutputPixelType* pixel, |
197 const T& value) | 88 const T& value) |
235 | 126 |
236 | 127 |
237 class VoxelReaderBase : public boost::noncopyable | 128 class VoxelReaderBase : public boost::noncopyable |
238 { | 129 { |
239 private: | 130 private: |
240 const ImageBuffer3D& image_; | 131 const Orthanc::ImageAccessor& image_; |
241 unsigned int width_; | 132 unsigned int width_; |
242 unsigned int height_; | 133 unsigned int height_; |
243 unsigned int depth_; | 134 unsigned int depth_; |
244 float widthFloat_; | 135 float widthFloat_; |
245 float heightFloat_; | 136 float heightFloat_; |
246 float depthFloat_; | 137 float depthFloat_; |
247 | 138 |
248 public: | 139 public: |
249 VoxelReaderBase(const ImageBuffer3D& image) : | 140 VoxelReaderBase(const ImageBuffer3D& image) : |
250 image_(image), | 141 image_(image.GetInternalImage()), |
251 width_(image.GetWidth()), | 142 width_(image.GetWidth()), |
252 height_(image.GetHeight()), | 143 height_(image.GetHeight()), |
253 depth_(image.GetDepth()), | 144 depth_(image.GetDepth()), |
254 widthFloat_(static_cast<float>(image.GetWidth())), | 145 widthFloat_(static_cast<float>(image.GetWidth())), |
255 heightFloat_(static_cast<float>(image.GetHeight())), | 146 heightFloat_(static_cast<float>(image.GetHeight())), |
256 depthFloat_(static_cast<float>(image.GetDepth())) | 147 depthFloat_(static_cast<float>(image.GetDepth())) |
257 { | 148 { |
258 } | 149 } |
259 | 150 |
260 const ImageBuffer3D& GetImage() const | 151 const Orthanc::ImageAccessor& GetImage() const |
261 { | 152 { |
262 return image_; | 153 return image_; |
263 } | 154 } |
264 | 155 |
265 const unsigned int GetImageWidth() const | 156 const unsigned int GetImageWidth() const |
329 template <Orthanc::PixelFormat InputFormat> | 220 template <Orthanc::PixelFormat InputFormat> |
330 class VoxelReader<InputFormat, ImageInterpolation_Nearest> : | 221 class VoxelReader<InputFormat, ImageInterpolation_Nearest> : |
331 public VoxelReaderBase | 222 public VoxelReaderBase |
332 { | 223 { |
333 public: | 224 public: |
334 typedef typename PixelTraits<InputFormat>::PixelType InputPixelType; | 225 typedef typename Orthanc::PixelTraits<InputFormat>::PixelType InputPixelType; |
335 | 226 |
336 VoxelReader(const ImageBuffer3D& image) : | 227 VoxelReader(const ImageBuffer3D& image) : |
337 VoxelReaderBase(image) | 228 VoxelReaderBase(image) |
338 { | 229 { |
339 } | 230 } |
359 | 250 |
360 if (GetNearestCoordinates(imageX, imageY, imageZ, | 251 if (GetNearestCoordinates(imageX, imageY, imageZ, |
361 fractionalX, fractionalY, fractionalZ, | 252 fractionalX, fractionalY, fractionalZ, |
362 volumeX, volumeY, volumeZ)) | 253 volumeX, volumeY, volumeZ)) |
363 { | 254 { |
364 PixelTraits<InputFormat>::GetVoxel(target, GetImage(), imageX, imageY, imageZ); | 255 Orthanc::ImageTraits<InputFormat>::GetPixel(target, GetImage(), imageX, |
256 imageY + imageZ * GetImageHeight()); | |
365 } | 257 } |
366 else | 258 else |
367 { | 259 { |
368 PixelTraits<InputFormat>::SetOutOfVolume(target); | 260 target = std::numeric_limits<InputPixelType>::min(); |
369 } | 261 } |
370 } | 262 } |
371 }; | 263 }; |
372 | 264 |
373 | 265 |
380 | 272 |
381 public: | 273 public: |
382 VoxelReader(const ImageBuffer3D& image) : | 274 VoxelReader(const ImageBuffer3D& image) : |
383 VoxelReaderBase(image) | 275 VoxelReaderBase(image) |
384 { | 276 { |
385 typename PixelTraits<InputFormat>::PixelType value; | 277 typedef typename Orthanc::PixelTraits<InputFormat>::PixelType Pixel; |
386 PixelTraits<InputFormat>::SetOutOfVolume(value); | 278 outOfVolume_ = static_cast<float>(std::numeric_limits<Pixel>::min()); |
387 outOfVolume_ = static_cast<float>(value); | |
388 } | 279 } |
389 | 280 |
390 void SampleVoxels(float& f00, | 281 void SampleVoxels(float& f00, |
391 float& f01, | 282 float& f01, |
392 float& f10, | 283 float& f10, |
393 float& f11, | 284 float& f11, |
394 unsigned int imageX, | 285 unsigned int imageX, |
395 unsigned int imageY, | 286 unsigned int imageY, |
396 unsigned int imageZ) const | 287 unsigned int imageZ) const |
397 { | 288 { |
398 f00 = PixelTraits<InputFormat>::GetFloatVoxel(GetImage(), imageX, imageY, imageZ); | 289 f00 = Orthanc::ImageTraits<InputFormat>::GetFloatPixel |
290 (GetImage(), imageX, imageY + imageZ * GetImageHeight()); | |
399 | 291 |
400 if (imageX + 1 < GetImageWidth()) | 292 if (imageX + 1 < GetImageWidth()) |
401 { | 293 { |
402 f01 = PixelTraits<InputFormat>::GetFloatVoxel(GetImage(), imageX + 1, imageY, imageZ); | 294 f01 = Orthanc::ImageTraits<InputFormat>::GetFloatPixel |
295 (GetImage(), imageX + 1, imageY + imageZ * GetImageHeight()); | |
403 } | 296 } |
404 else | 297 else |
405 { | 298 { |
406 f01 = f00; | 299 f01 = f00; |
407 } | 300 } |
408 | 301 |
409 if (imageY + 1 < GetImageWidth()) | 302 if (imageY + 1 < GetImageWidth()) |
410 { | 303 { |
411 f10 = PixelTraits<InputFormat>::GetFloatVoxel(GetImage(), imageX, imageY + 1, imageZ); | 304 f10 = Orthanc::ImageTraits<InputFormat>::GetFloatPixel |
305 (GetImage(), imageX, imageY + 1 + imageZ * GetImageHeight()); | |
412 } | 306 } |
413 else | 307 else |
414 { | 308 { |
415 f10 = f00; | 309 f10 = f00; |
416 } | 310 } |
417 | 311 |
418 if (imageX + 1 < GetImageWidth() && | 312 if (imageX + 1 < GetImageWidth() && |
419 imageY + 1 < GetImageHeight()) | 313 imageY + 1 < GetImageHeight()) |
420 { | 314 { |
421 f11 = PixelTraits<InputFormat>::GetFloatVoxel(GetImage(), imageX + 1, imageY + 1, imageZ); | 315 f11 = Orthanc::ImageTraits<InputFormat>::GetFloatPixel |
316 (GetImage(), imageX + 1, imageY + 1 + imageZ * GetImageHeight()); | |
422 } | 317 } |
423 else | 318 else |
424 { | 319 { |
425 f11 = f00; | 320 f11 = f00; |
426 } | 321 } |
738 | 633 |
739 Shader shader(source, scaling, offset); | 634 Shader shader(source, scaling, offset); |
740 | 635 |
741 for (unsigned int y = 0; y < outputHeight; y++) | 636 for (unsigned int y = 0; y < outputHeight; y++) |
742 { | 637 { |
743 typename Writer::OutputPixelType* p = reinterpret_cast<typename Writer::OutputPixelType*>(slice.GetRow(y)); | 638 typename Writer::OutputPixelType* p = |
639 reinterpret_cast<typename Writer::OutputPixelType*>(slice.GetRow(y)); | |
744 | 640 |
745 RowIterator it(slice, extent, plane, box, y); | 641 RowIterator it(slice, extent, plane, box, y); |
746 | 642 |
747 for (unsigned int x = 0; x < outputWidth; x++, p++) | 643 for (unsigned int x = 0; x < outputWidth; x++, p++) |
748 { | 644 { |