changeset 1781:bf4b15b059ea

unit test VolumeRendering.FlipAxial
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 14 May 2021 15:35:24 +0200
parents b7c9fd1e9fb0
children f053c80ea411
files UnitTestsSources/VolumeRenderingTests.cpp
diffstat 1 files changed, 196 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/UnitTestsSources/VolumeRenderingTests.cpp	Fri May 14 11:39:11 2021 +0200
+++ b/UnitTestsSources/VolumeRenderingTests.cpp	Fri May 14 15:35:24 2021 +0200
@@ -20,8 +20,8 @@
 
 
 #include "../OrthancStone/Sources/Scene2D/CairoCompositor.h"
+#include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h"
 #include "../OrthancStone/Sources/Scene2D/CopyStyleConfigurator.h"
-#include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h"
 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.h"
 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageReslicer.h"
 
@@ -95,6 +95,57 @@
 }
 
 
+static bool IsConstImageWithExclusion(float value,
+                                      const Orthanc::ImageAccessor& image,
+                                      unsigned int exclusionX,
+                                      unsigned int exclusionY,
+                                      unsigned int exclusionWidth,
+                                      unsigned int exclusionHeight)
+{
+  for (unsigned int y = 0; y < image.GetHeight(); y++)
+  {
+    for (unsigned int x = 0; x < image.GetWidth(); x++)
+    {
+      if ((x < exclusionX ||
+           y < exclusionY ||
+           x >= exclusionX + exclusionWidth ||
+           y >= exclusionY + exclusionHeight) &&
+          !OrthancStone::LinearAlgebra::IsNear(value, GetPixelValue(image, x, y)))
+      {
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+
+static bool AreSameImages(const Orthanc::ImageAccessor& image1,
+                          const Orthanc::ImageAccessor& image2)
+{
+  if (image1.GetWidth() != image2.GetWidth() ||
+      image1.GetHeight() != image2.GetHeight())
+  {
+    return false;
+  }
+  
+  for (unsigned int y = 0; y < image1.GetHeight(); y++)
+  {
+    for (unsigned int x = 0; x < image1.GetWidth(); x++)
+    {
+      if (!OrthancStone::LinearAlgebra::IsNear(GetPixelValue(image1, x, y),
+                                               GetPixelValue(image2, x, y)))
+      {
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+  
+
 static void Assign3x3Pattern(Orthanc::ImageAccessor& image)
 {
   if (image.GetFormat() == Orthanc::PixelFormat_Grayscale8 &&
@@ -429,3 +480,147 @@
     ASSERT_TRUE(IsConstRegion(0.0f, *rendered, 0, 27, 36, 3));
   }
 }
+
+
+TEST(VolumeRendering, FlipAxial)
+{
+  double x = 2;
+  double y = 1;
+  OrthancStone::CoordinateSystem3D axial(OrthancStone::LinearAlgebra::CreateVector(x, y, 0),
+                                         OrthancStone::LinearAlgebra::CreateVector(1, 0, 0),
+                                         OrthancStone::LinearAlgebra::CreateVector(0, 1, 0));
+
+  Orthanc::Image pattern(Orthanc::PixelFormat_Grayscale8, 3, 3, false);
+  Assign3x3Pattern(pattern);
+  
+  Orthanc::Image patternX(Orthanc::PixelFormat_Grayscale8, 3, 3, false);
+  Assign3x3Pattern(patternX);
+  Orthanc::ImageProcessing::FlipX(patternX);
+  
+  Orthanc::Image patternY(Orthanc::PixelFormat_Grayscale8, 3, 3, false);
+  Assign3x3Pattern(patternY);
+  Orthanc::ImageProcessing::FlipY(patternY);
+  
+  Orthanc::Image patternXY(Orthanc::PixelFormat_Grayscale8, 3, 3, false);
+  Assign3x3Pattern(patternXY);
+  Orthanc::ImageProcessing::FlipX(patternXY);
+  Orthanc::ImageProcessing::FlipY(patternXY);
+    
+  for (unsigned int mode = 0; mode < 2; mode++)
+  {
+    {
+      OrthancStone::CoordinateSystem3D cuttingPlane(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0),
+                                                    OrthancStone::LinearAlgebra::CreateVector(1, 0, 0),
+                                                    OrthancStone::LinearAlgebra::CreateVector(0, 1, 0));
+
+      std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer(Slice3x3x1Pattern(axial, cuttingPlane, static_cast<SlicerType>(mode)));
+      ASSERT_TRUE(AreSameImages(layer->GetTexture(), pattern));
+
+      OrthancStone::Extent2D extent;
+      layer->GetBoundingBox(extent);
+      ASSERT_FLOAT_EQ(x - 0.5, extent.GetX1());
+      ASSERT_FLOAT_EQ(y - 0.5, extent.GetY1());
+      ASSERT_FLOAT_EQ(x + 2.5, extent.GetX2());
+      ASSERT_FLOAT_EQ(y + 2.5, extent.GetY2());
+
+      std::unique_ptr<Orthanc::ImageAccessor> rendered(Render(layer.release(), 15, 15));
+      ASSERT_TRUE(IsConstImageWithExclusion(0.0f, *rendered, 9, 8, 3, 3));
+
+      Orthanc::ImageAccessor p;
+      rendered->GetRegion(p, 9, 8, 3, 3);
+      ASSERT_TRUE(AreSameImages(p, pattern));
+    }
+
+    {
+      OrthancStone::CoordinateSystem3D cuttingPlane(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0),
+                                                    OrthancStone::LinearAlgebra::CreateVector(-1, 0, 0),
+                                                    OrthancStone::LinearAlgebra::CreateVector(0, 1, 0));
+
+      std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer(Slice3x3x1Pattern(axial, cuttingPlane, static_cast<SlicerType>(mode)));
+      if (mode == 1)
+      {
+        // Reslicer directly flips the pixels of the texture
+        ASSERT_TRUE(AreSameImages(layer->GetTexture(), patternX));
+      }
+      else
+      {
+        // MPR slicer uses "TextureBaseSceneLayer::SetTransform()" to flip
+        ASSERT_TRUE(AreSameImages(layer->GetTexture(), pattern));
+      }
+
+      OrthancStone::Extent2D extent;
+      layer->GetBoundingBox(extent);
+      ASSERT_FLOAT_EQ(-(x + 2.5), extent.GetX1());
+      ASSERT_FLOAT_EQ(y - 0.5, extent.GetY1());
+      ASSERT_FLOAT_EQ(-(x - 0.5), extent.GetX2());
+      ASSERT_FLOAT_EQ(y + 2.5, extent.GetY2());
+
+      std::unique_ptr<Orthanc::ImageAccessor> rendered(Render(layer.release(), 15, 15));
+      ASSERT_TRUE(IsConstImageWithExclusion(0.0f, *rendered, 3, 8, 3, 3));
+
+      Orthanc::ImageAccessor p;
+      rendered->GetRegion(p, 3, 8, 3, 3);
+      ASSERT_TRUE(AreSameImages(p, patternX));
+    }
+
+    {
+      OrthancStone::CoordinateSystem3D cuttingPlane(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0),
+                                                    OrthancStone::LinearAlgebra::CreateVector(1, 0, 0),
+                                                    OrthancStone::LinearAlgebra::CreateVector(0, -1, 0));
+
+      std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer(Slice3x3x1Pattern(axial, cuttingPlane, static_cast<SlicerType>(mode)));
+      if (mode == 1)
+      {
+        ASSERT_TRUE(AreSameImages(layer->GetTexture(), patternY));
+      }
+      else
+      {
+        ASSERT_TRUE(AreSameImages(layer->GetTexture(), pattern));
+      }
+
+      OrthancStone::Extent2D extent;
+      layer->GetBoundingBox(extent);
+      ASSERT_FLOAT_EQ(x - 0.5, extent.GetX1());
+      ASSERT_FLOAT_EQ(-(y + 2.5), extent.GetY1());
+      ASSERT_FLOAT_EQ(x + 2.5, extent.GetX2());
+      ASSERT_FLOAT_EQ(-(y - 0.5), extent.GetY2());
+
+      std::unique_ptr<Orthanc::ImageAccessor> rendered(Render(layer.release(), 15, 15));
+      ASSERT_TRUE(IsConstImageWithExclusion(0.0f, *rendered, 9, 4, 3, 3));
+
+      Orthanc::ImageAccessor p;
+      rendered->GetRegion(p, 9, 4, 3, 3);
+      ASSERT_TRUE(AreSameImages(p, patternY));
+    }
+
+    {
+      OrthancStone::CoordinateSystem3D cuttingPlane(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0),
+                                                    OrthancStone::LinearAlgebra::CreateVector(-1, 0, 0),
+                                                    OrthancStone::LinearAlgebra::CreateVector(0, -1, 0));
+
+      std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer(Slice3x3x1Pattern(axial, cuttingPlane, static_cast<SlicerType>(mode)));
+      if (mode == 1)
+      {
+        ASSERT_TRUE(AreSameImages(layer->GetTexture(), patternXY));
+      }
+      else
+      {
+        ASSERT_TRUE(AreSameImages(layer->GetTexture(), pattern));
+      }
+
+      OrthancStone::Extent2D extent;
+      layer->GetBoundingBox(extent);
+      ASSERT_FLOAT_EQ(-(x + 2.5), extent.GetX1());
+      ASSERT_FLOAT_EQ(-(y + 2.5), extent.GetY1());
+      ASSERT_FLOAT_EQ(-(x - 0.5), extent.GetX2());
+      ASSERT_FLOAT_EQ(-(y - 0.5), extent.GetY2());
+
+      std::unique_ptr<Orthanc::ImageAccessor> rendered(Render(layer.release(), 15, 15));
+      ASSERT_TRUE(IsConstImageWithExclusion(0.0f, *rendered, 3, 4, 3, 3));
+
+      Orthanc::ImageAccessor p;
+      rendered->GetRegion(p, 3, 4, 3, 3);
+      ASSERT_TRUE(AreSameImages(p, patternXY));
+    }
+  }
+}