Mercurial > hg > orthanc-stone
comparison Framework/Volumes/VolumeReslicer.cpp @ 860:238693c3bc51 am-dev
merge default -> am-dev
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Mon, 24 Jun 2019 14:35:00 +0200 |
parents | cd13a062c9bd |
children | a7351ad54960 |
comparison
equal
deleted
inserted
replaced
856:a6e17a5a39e7 | 860:238693c3bc51 |
---|---|
228 | 228 |
229 public: | 229 public: |
230 FastRowIterator(const Orthanc::ImageAccessor& slice, | 230 FastRowIterator(const Orthanc::ImageAccessor& slice, |
231 const Extent2D& extent, | 231 const Extent2D& extent, |
232 const CoordinateSystem3D& plane, | 232 const CoordinateSystem3D& plane, |
233 const OrientedBoundingBox& box, | 233 const OrientedVolumeBoundingBox& box, |
234 unsigned int y) | 234 unsigned int y) |
235 { | 235 { |
236 const double width = static_cast<double>(slice.GetWidth()); | 236 const double width = static_cast<double>(slice.GetWidth()); |
237 const double height = static_cast<double>(slice.GetHeight()); | 237 const double height = static_cast<double>(slice.GetHeight()); |
238 assert(y < height); | 238 assert(y < height); |
283 { | 283 { |
284 private: | 284 private: |
285 const Orthanc::ImageAccessor& slice_; | 285 const Orthanc::ImageAccessor& slice_; |
286 const Extent2D& extent_; | 286 const Extent2D& extent_; |
287 const CoordinateSystem3D& plane_; | 287 const CoordinateSystem3D& plane_; |
288 const OrientedBoundingBox& box_; | 288 const OrientedVolumeBoundingBox& box_; |
289 unsigned int x_; | 289 unsigned int x_; |
290 unsigned int y_; | 290 unsigned int y_; |
291 | 291 |
292 public: | 292 public: |
293 SlowRowIterator(const Orthanc::ImageAccessor& slice, | 293 SlowRowIterator(const Orthanc::ImageAccessor& slice, |
294 const Extent2D& extent, | 294 const Extent2D& extent, |
295 const CoordinateSystem3D& plane, | 295 const CoordinateSystem3D& plane, |
296 const OrientedBoundingBox& box, | 296 const OrientedVolumeBoundingBox& box, |
297 unsigned int y) : | 297 unsigned int y) : |
298 slice_(slice), | 298 slice_(slice), |
299 extent_(extent), | 299 extent_(extent), |
300 plane_(plane), | 300 plane_(plane), |
301 box_(box), | 301 box_(box), |
340 TransferFunction Function> | 340 TransferFunction Function> |
341 static void ProcessImage(Orthanc::ImageAccessor& slice, | 341 static void ProcessImage(Orthanc::ImageAccessor& slice, |
342 const Extent2D& extent, | 342 const Extent2D& extent, |
343 const ImageBuffer3D& source, | 343 const ImageBuffer3D& source, |
344 const CoordinateSystem3D& plane, | 344 const CoordinateSystem3D& plane, |
345 const OrientedBoundingBox& box, | 345 const OrientedVolumeBoundingBox& box, |
346 float scaling, | 346 float scaling, |
347 float offset) | 347 float offset) |
348 { | 348 { |
349 typedef PixelShader<InputFormat, OutputFormat, Interpolation, Function> Shader; | 349 typedef PixelShader<InputFormat, OutputFormat, Interpolation, Function> Shader; |
350 | 350 |
384 Orthanc::PixelFormat OutputFormat> | 384 Orthanc::PixelFormat OutputFormat> |
385 static void ProcessImage(Orthanc::ImageAccessor& slice, | 385 static void ProcessImage(Orthanc::ImageAccessor& slice, |
386 const Extent2D& extent, | 386 const Extent2D& extent, |
387 const ImageBuffer3D& source, | 387 const ImageBuffer3D& source, |
388 const CoordinateSystem3D& plane, | 388 const CoordinateSystem3D& plane, |
389 const OrientedBoundingBox& box, | 389 const OrientedVolumeBoundingBox& box, |
390 ImageInterpolation interpolation, | 390 ImageInterpolation interpolation, |
391 bool hasLinearFunction, | 391 bool hasLinearFunction, |
392 float scaling, | 392 float scaling, |
393 float offset) | 393 float offset) |
394 { | 394 { |
450 template <typename RowIterator> | 450 template <typename RowIterator> |
451 static void ProcessImage(Orthanc::ImageAccessor& slice, | 451 static void ProcessImage(Orthanc::ImageAccessor& slice, |
452 const Extent2D& extent, | 452 const Extent2D& extent, |
453 const ImageBuffer3D& source, | 453 const ImageBuffer3D& source, |
454 const CoordinateSystem3D& plane, | 454 const CoordinateSystem3D& plane, |
455 const OrientedBoundingBox& box, | 455 const OrientedVolumeBoundingBox& box, |
456 ImageInterpolation interpolation, | 456 ImageInterpolation interpolation, |
457 bool hasLinearFunction, | 457 bool hasLinearFunction, |
458 float scaling, | 458 float scaling, |
459 float offset) | 459 float offset) |
460 { | 460 { |
499 | 499 |
500 | 500 |
501 | 501 |
502 void VolumeReslicer::CheckIterators(const ImageBuffer3D& source, | 502 void VolumeReslicer::CheckIterators(const ImageBuffer3D& source, |
503 const CoordinateSystem3D& plane, | 503 const CoordinateSystem3D& plane, |
504 const OrientedBoundingBox& box) const | 504 const OrientedVolumeBoundingBox& box) const |
505 { | 505 { |
506 for (unsigned int y = 0; y < slice_->GetHeight(); y++) | 506 for (unsigned int y = 0; y < slice_->GetHeight(); y++) |
507 { | 507 { |
508 FastRowIterator fast(*slice_, extent_, plane, box, y); | 508 FastRowIterator fast(*slice_, extent_, plane, box, y); |
509 SlowRowIterator slow(*slice_, extent_, plane, box, y); | 509 SlowRowIterator slow(*slice_, extent_, plane, box, y); |
743 } | 743 } |
744 } | 744 } |
745 | 745 |
746 | 746 |
747 void VolumeReslicer::Apply(const ImageBuffer3D& source, | 747 void VolumeReslicer::Apply(const ImageBuffer3D& source, |
748 const VolumeImageGeometry& geometry, | |
748 const CoordinateSystem3D& plane) | 749 const CoordinateSystem3D& plane) |
749 { | 750 { |
750 // Choose the default voxel size as the finest voxel dimension | 751 // Choose the default voxel size as the finest voxel dimension |
751 // of the source volumetric image | 752 // of the source volumetric image |
752 const OrthancStone::Vector dim = | 753 const OrthancStone::Vector dim = |
753 source.GetGeometry().GetVoxelDimensions(OrthancStone::VolumeProjection_Axial); | 754 geometry.GetVoxelDimensions(OrthancStone::VolumeProjection_Axial); |
754 double voxelSize = dim[0]; | 755 double voxelSize = dim[0]; |
755 | 756 |
756 if (dim[1] < voxelSize) | 757 if (dim[1] < voxelSize) |
757 { | 758 { |
758 voxelSize = dim[1]; | 759 voxelSize = dim[1]; |
766 if (voxelSize <= 0) | 767 if (voxelSize <= 0) |
767 { | 768 { |
768 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | 769 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
769 } | 770 } |
770 | 771 |
771 Apply(source, plane, voxelSize); | 772 Apply(source, geometry, plane, voxelSize); |
772 } | 773 } |
773 | 774 |
774 | 775 |
775 void VolumeReslicer::Apply(const ImageBuffer3D& source, | 776 void VolumeReslicer::Apply(const ImageBuffer3D& source, |
777 const VolumeImageGeometry& geometry, | |
776 const CoordinateSystem3D& plane, | 778 const CoordinateSystem3D& plane, |
777 double voxelSize) | 779 double voxelSize) |
778 { | 780 { |
779 Reset(); | 781 Reset(); |
782 pixelSpacing_ = voxelSize; | |
780 | 783 |
781 // Firstly, compute the intersection of the source volumetric | 784 // Firstly, compute the intersection of the source volumetric |
782 // image with the reslicing plane. This leads to a polygon with 3 | 785 // image with the reslicing plane. This leads to a polygon with 3 |
783 // to 6 vertices. We compute the extent of the intersection | 786 // to 6 vertices. We compute the extent of the intersection |
784 // polygon, with respect to the coordinate system of the reslicing | 787 // polygon, with respect to the coordinate system of the reslicing |
785 // plane. | 788 // plane. |
786 OrientedBoundingBox box(source); | 789 OrientedVolumeBoundingBox box(geometry); |
787 | 790 |
788 if (!box.ComputeExtent(extent_, plane)) | 791 if (!box.ComputeExtent(extent_, plane)) |
789 { | 792 { |
790 // The plane does not intersect with the bounding box of the volume | 793 // The plane does not intersect with the bounding box of the volume |
791 slice_.reset(new Orthanc::Image(outputFormat_, 0, 0, false)); | 794 slice_.reset(new Orthanc::Image(outputFormat_, 0, 0, false)); |
813 interpolation_, hasLinearFunction_, scaling_, offset_); | 816 interpolation_, hasLinearFunction_, scaling_, offset_); |
814 } | 817 } |
815 | 818 |
816 success_ = true; | 819 success_ = true; |
817 } | 820 } |
821 | |
822 | |
823 double VolumeReslicer::GetPixelSpacing() const | |
824 { | |
825 if (success_) | |
826 { | |
827 return pixelSpacing_; | |
828 } | |
829 else | |
830 { | |
831 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
832 } | |
833 } | |
818 } | 834 } |