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 }