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 {