changeset 1774:95ece40bb298

DicomVolumeImageReslicer and DicomVolumeImageMPRSlicer behave identically on axial
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 12 May 2021 17:43:51 +0200
parents 34eb41352dff
children fca942f4b4a7
files OrthancStone/Sources/Volumes/VolumeReslicer.cpp UnitTestsSources/VolumeRenderingTests.cpp
diffstat 2 files changed, 78 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancStone/Sources/Volumes/VolumeReslicer.cpp	Wed May 12 17:40:38 2021 +0200
+++ b/OrthancStone/Sources/Volumes/VolumeReslicer.cpp	Wed May 12 17:43:51 2021 +0200
@@ -239,12 +239,12 @@
         assert(y < height);
 
         Vector q1 = plane.MapSliceToWorldCoordinates
-          (extent.GetX1() + extent.GetWidth() * static_cast<double>(0) / static_cast<double>(width + 1),
-           extent.GetY1() + extent.GetHeight() * static_cast<double>(y) / static_cast<double>(height + 1));
+          (extent.GetX1() + extent.GetWidth() * 0.5 / width,
+           extent.GetY1() + extent.GetHeight() * (static_cast<double>(y) + 0.5) / height);
 
         Vector q2 = plane.MapSliceToWorldCoordinates
-          (extent.GetX1() + extent.GetWidth() * static_cast<double>(width - 1) / static_cast<double>(width + 1),
-           extent.GetY1() + extent.GetHeight() * static_cast<double>(y) / static_cast<double>(height + 1));
+          (extent.GetX1() + extent.GetWidth() * (static_cast<double>(width - 1) + 0.5) / width,
+           extent.GetY1() + extent.GetHeight() * (static_cast<double>(y) + 0.5) / height);
 
         Vector r1, r2;
         box.ToInternalCoordinates(r1, q1);
@@ -321,8 +321,8 @@
         const double height = static_cast<double>(slice_.GetHeight());
         
         Vector q = plane_.MapSliceToWorldCoordinates
-          (extent_.GetX1() + extent_.GetWidth() * static_cast<double>(x_) / (width + 1.0),
-           extent_.GetY1() + extent_.GetHeight() * static_cast<double>(y_) / (height + 1.0));
+          (extent_.GetX1() + extent_.GetWidth() * (static_cast<double>(x_) + 0.5) / width,
+           extent_.GetY1() + extent_.GetHeight() * (static_cast<double>(y_) + 0.5) / height);
 
         Vector r;
         box_.ToInternalCoordinates(r, q);
--- a/UnitTestsSources/VolumeRenderingTests.cpp	Wed May 12 17:40:38 2021 +0200
+++ b/UnitTestsSources/VolumeRenderingTests.cpp	Wed May 12 17:43:51 2021 +0200
@@ -64,72 +64,84 @@
 
   OrthancStone::CoordinateSystem3D viewpoint;
 
-  //OrthancStone::DicomVolumeImageReslicer slicer(volume); slicer.SetInterpolation(OrthancStone::ImageInterpolation_Nearest);
-  OrthancStone::DicomVolumeImageMPRSlicer slicer(volume);
-  std::unique_ptr<OrthancStone::IVolumeSlicer::IExtractedSlice> slice(slicer.ExtractSlice(viewpoint));
-  ASSERT_TRUE(slice->IsValid());
-
-  OrthancStone::CopyStyleConfigurator configurator;
-  std::unique_ptr<OrthancStone::ISceneLayer> layer(slice->CreateSceneLayer(&configurator, viewpoint));
+  for (unsigned int mode = 0; mode < 2; mode++)
+  {
+    std::unique_ptr<OrthancStone::IVolumeSlicer> slicer;
 
-  {
-    const Orthanc::ImageAccessor& a = dynamic_cast<OrthancStone::TextureBaseSceneLayer&>(*layer).GetTexture();
-    Orthanc::Image i(Orthanc::PixelFormat_Grayscale8, a.GetWidth(), a.GetHeight(), false);
-    Orthanc::ImageProcessing::Convert(i, a);
+    if (mode == 1)
+    {
+      slicer.reset(new OrthancStone::DicomVolumeImageReslicer(volume));
+    }
+    else
+    {    
+      slicer.reset(new OrthancStone::DicomVolumeImageMPRSlicer(volume));
+    }
+  
+    std::unique_ptr<OrthancStone::IVolumeSlicer::IExtractedSlice> slice(slicer->ExtractSlice(viewpoint));
+    ASSERT_TRUE(slice->IsValid());
 
-    ASSERT_EQ(3u, i.GetWidth());
-    ASSERT_EQ(3u, i.GetHeight());
+    OrthancStone::CopyStyleConfigurator configurator;
+    std::unique_ptr<OrthancStone::ISceneLayer> layer(slice->CreateSceneLayer(&configurator, viewpoint));
 
-    ASSERT_FLOAT_EQ(0, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 0, 0));
-    ASSERT_FLOAT_EQ(25, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 1, 0));
-    ASSERT_FLOAT_EQ(50, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 2, 0));
-    ASSERT_FLOAT_EQ(75, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 0, 1));
-    ASSERT_FLOAT_EQ(100, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 1, 1));
-    ASSERT_FLOAT_EQ(125, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 2, 1));
-    ASSERT_FLOAT_EQ(150, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 0, 2));
-    ASSERT_FLOAT_EQ(175, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 1, 2));
-    ASSERT_FLOAT_EQ(200, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 2, 2));
-  }
+    {
+      const Orthanc::ImageAccessor& a = dynamic_cast<OrthancStone::TextureBaseSceneLayer&>(*layer).GetTexture();
+      Orthanc::Image i(Orthanc::PixelFormat_Grayscale8, a.GetWidth(), a.GetHeight(), false);
+      Orthanc::ImageProcessing::Convert(i, a);
+
+      ASSERT_EQ(3u, i.GetWidth());
+      ASSERT_EQ(3u, i.GetHeight());
 
-  OrthancStone::Scene2D scene;  // Scene is initialized with the identity viewpoint
-  scene.SetLayer(0, layer.release());
-
-  OrthancStone::CairoCompositor compositor(5, 5);
-  compositor.Refresh(scene);
+      ASSERT_FLOAT_EQ(0, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 0, 0));
+      ASSERT_FLOAT_EQ(25, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 1, 0));
+      ASSERT_FLOAT_EQ(50, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 2, 0));
+      ASSERT_FLOAT_EQ(75, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 0, 1));
+      ASSERT_FLOAT_EQ(100, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 1, 1));
+      ASSERT_FLOAT_EQ(125, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 2, 1));
+      ASSERT_FLOAT_EQ(150, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 0, 2));
+      ASSERT_FLOAT_EQ(175, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 1, 2));
+      ASSERT_FLOAT_EQ(200, Orthanc::ImageTraits<Orthanc::PixelFormat_Grayscale8>::GetFloatPixel(i, 2, 2));
+    }
 
-  Orthanc::ImageAccessor i;
-  compositor.GetCanvas().GetReadOnlyAccessor(i);
+    OrthancStone::Scene2D scene;  // Scene is initialized with the identity viewpoint
+    scene.SetLayer(0, layer.release());
+
+    OrthancStone::CairoCompositor compositor(5, 5);
+    compositor.Refresh(scene);
 
-  Orthanc::Image j(Orthanc::PixelFormat_RGB24, i.GetWidth(), i.GetHeight(), false);
-  Orthanc::ImageProcessing::Convert(j, i);
+    Orthanc::ImageAccessor i;
+    compositor.GetCanvas().GetReadOnlyAccessor(i);
+
+    Orthanc::Image j(Orthanc::PixelFormat_RGB24, i.GetWidth(), i.GetHeight(), false);
+    Orthanc::ImageProcessing::Convert(j, i);
 
-  ASSERT_EQ(5u, j.GetWidth());
-  ASSERT_EQ(5u, j.GetHeight());
-  Orthanc::PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel;
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 0);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 0);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 0);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 0);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 0);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 1);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 1);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 1);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 1);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 1);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 2);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 2);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 2);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 2);  ASSERT_EQ(25, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 2);  ASSERT_EQ(50, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 3);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 3);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 3);  ASSERT_EQ(75, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 3);  ASSERT_EQ(100, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 3);  ASSERT_EQ(125, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 4);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 4);  ASSERT_EQ(0, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 4);  ASSERT_EQ(150, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 4);  ASSERT_EQ(175, pixel.red_);
-  Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 4);  ASSERT_EQ(200, pixel.red_);
+    ASSERT_EQ(5u, j.GetWidth());
+    ASSERT_EQ(5u, j.GetHeight());
+    Orthanc::PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel;
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 0);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 0);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 0);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 0);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 0);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 1);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 1);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 1);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 1);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 1);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 2);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 2);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 2);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 2);  ASSERT_EQ(25, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 2);  ASSERT_EQ(50, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 3);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 3);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 3);  ASSERT_EQ(75, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 3);  ASSERT_EQ(100, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 3);  ASSERT_EQ(125, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 0, 4);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 1, 4);  ASSERT_EQ(0, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 2, 4);  ASSERT_EQ(150, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 3, 4);  ASSERT_EQ(175, pixel.red_);
+    Orthanc::ImageTraits<Orthanc::PixelFormat_RGB24>::GetPixel(pixel, j, 4, 4);  ASSERT_EQ(200, pixel.red_);
+  }
 }