Mercurial > hg > orthanc-stone
diff UnitTestsSources/VolumeRenderingTests.cpp @ 1783:75d3e2ab1fe1
BREAKING: SubvoxelReader using the same Z-axis ordering as ImageBuffer3D
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 14 May 2021 18:30:24 +0200 |
parents | f053c80ea411 |
children | 42a2880d690f |
line wrap: on
line diff
--- a/UnitTestsSources/VolumeRenderingTests.cpp Fri May 14 16:30:54 2021 +0200 +++ b/UnitTestsSources/VolumeRenderingTests.cpp Fri May 14 18:30:24 2021 +0200 @@ -22,6 +22,7 @@ #include "../OrthancStone/Sources/Scene2D/CairoCompositor.h" #include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h" #include "../OrthancStone/Sources/Scene2D/CopyStyleConfigurator.h" +#include "../OrthancStone/Sources/Toolbox/SubvoxelReader.h" #include "../OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.h" #include "../OrthancStone/Sources/Volumes/DicomVolumeImageReslicer.h" @@ -32,6 +33,7 @@ #include <gtest/gtest.h> + static float GetPixelValue(const Orthanc::ImageAccessor& image, unsigned int x, unsigned int y) @@ -298,6 +300,161 @@ } +TEST(VolumeRendering, Pattern) +{ + { + // Axial + OrthancStone::ImageBuffer3D image(Orthanc::PixelFormat_Grayscale8, 3, 3, 1, true); + + { + OrthancStone::ImageBuffer3D::SliceWriter writer(image, OrthancStone::VolumeProjection_Axial, 0); + Assign3x3Pattern(writer.GetAccessor()); + } + + float a, b; + ASSERT_TRUE(image.GetRange(a, b)); + ASSERT_FLOAT_EQ(0, a); + ASSERT_FLOAT_EQ(200, b); + + ASSERT_EQ(0, image.GetVoxelGrayscale8(0, 0, 0)); + ASSERT_EQ(25, image.GetVoxelGrayscale8(1, 0, 0)); + ASSERT_EQ(50, image.GetVoxelGrayscale8(2, 0, 0)); + ASSERT_EQ(75, image.GetVoxelGrayscale8(0, 1, 0)); + ASSERT_EQ(100, image.GetVoxelGrayscale8(1, 1, 0)); + ASSERT_EQ(125, image.GetVoxelGrayscale8(2, 1, 0)); + ASSERT_EQ(150, image.GetVoxelGrayscale8(0, 2, 0)); + ASSERT_EQ(175, image.GetVoxelGrayscale8(1, 2, 0)); + ASSERT_EQ(200, image.GetVoxelGrayscale8(2, 2, 0)); + + float v; + OrthancStone::SubvoxelReader<Orthanc::PixelFormat_Grayscale8, + OrthancStone::ImageInterpolation_Nearest> reader(image); + + ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(0, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(25, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(50, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 1.01, 0.01)); ASSERT_FLOAT_EQ(75, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 1.01, 0.01)); ASSERT_FLOAT_EQ(100, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 1.01, 0.01)); ASSERT_FLOAT_EQ(125, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 2.01, 0.01)); ASSERT_FLOAT_EQ(150, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 2.01, 0.01)); ASSERT_FLOAT_EQ(175, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 2.01, 0.01)); ASSERT_FLOAT_EQ(200, v); + + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(0, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(25, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(50, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 1.99, 0.99)); ASSERT_FLOAT_EQ(75, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 1.99, 0.99)); ASSERT_FLOAT_EQ(100, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 1.99, 0.99)); ASSERT_FLOAT_EQ(125, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 2.99, 0.99)); ASSERT_FLOAT_EQ(150, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 2.99, 0.99)); ASSERT_FLOAT_EQ(175, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 2.99, 0.99)); ASSERT_FLOAT_EQ(200, v); + } + + { + // Coronal + OrthancStone::ImageBuffer3D image(Orthanc::PixelFormat_Grayscale8, 3, 1, 3, true); + + { + OrthancStone::ImageBuffer3D::SliceWriter writer(image, OrthancStone::VolumeProjection_Coronal, 0); + Assign3x3Pattern(writer.GetAccessor()); + } + + float a, b; + ASSERT_TRUE(image.GetRange(a, b)); + ASSERT_FLOAT_EQ(0, a); + ASSERT_FLOAT_EQ(200, b); + + // "Z" is in reverse order in "Assign3x3Pattern()", because important note in "ImageBuffer3D" + ASSERT_EQ(0, image.GetVoxelGrayscale8(0, 0, 2)); + ASSERT_EQ(25, image.GetVoxelGrayscale8(1, 0, 2)); + ASSERT_EQ(50, image.GetVoxelGrayscale8(2, 0, 2)); + ASSERT_EQ(75, image.GetVoxelGrayscale8(0, 0, 1)); + ASSERT_EQ(100, image.GetVoxelGrayscale8(1, 0, 1)); + ASSERT_EQ(125, image.GetVoxelGrayscale8(2, 0, 1)); + ASSERT_EQ(150, image.GetVoxelGrayscale8(0, 0, 0)); + ASSERT_EQ(175, image.GetVoxelGrayscale8(1, 0, 0)); + ASSERT_EQ(200, image.GetVoxelGrayscale8(2, 0, 0)); + + // Ensure that "SubvoxelReader" is consistent with "image.GetVoxelGrayscale8()" + float v; + OrthancStone::SubvoxelReader<Orthanc::PixelFormat_Grayscale8, + OrthancStone::ImageInterpolation_Nearest> reader(image); + + ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 0.01, 2.01)); ASSERT_FLOAT_EQ(0, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 0.01, 2.01)); ASSERT_FLOAT_EQ(25, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 0.01, 2.01)); ASSERT_FLOAT_EQ(50, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 0.01, 1.01)); ASSERT_FLOAT_EQ(75, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 0.01, 1.01)); ASSERT_FLOAT_EQ(100, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 0.01, 1.01)); ASSERT_FLOAT_EQ(125, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(150, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(175, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.01, 0.01, 0.01)); ASSERT_FLOAT_EQ(200, v); + + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 2.99)); ASSERT_FLOAT_EQ(0, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 0.99, 2.99)); ASSERT_FLOAT_EQ(25, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 0.99, 2.99)); ASSERT_FLOAT_EQ(50, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 1.99)); ASSERT_FLOAT_EQ(75, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 0.99, 1.99)); ASSERT_FLOAT_EQ(100, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 0.99, 1.99)); ASSERT_FLOAT_EQ(125, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(150, v); + ASSERT_TRUE(reader.GetFloatValue(v, 1.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(175, v); + ASSERT_TRUE(reader.GetFloatValue(v, 2.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(200, v); + } + + { + // Sagittal + OrthancStone::ImageBuffer3D image(Orthanc::PixelFormat_Grayscale8, 1, 3, 3, true); + + { + OrthancStone::ImageBuffer3D::SliceWriter writer(image, OrthancStone::VolumeProjection_Sagittal, 0); + Assign3x3Pattern(writer.GetAccessor()); + } + + float a, b; + ASSERT_TRUE(image.GetRange(a, b)); + ASSERT_FLOAT_EQ(0, a); + ASSERT_FLOAT_EQ(200, b); + + // "Z" is in reverse order in "Assign3x3Pattern()", because important note in "ImageBuffer3D" + ASSERT_EQ(0, image.GetVoxelGrayscale8(0, 0, 2)); + ASSERT_EQ(25, image.GetVoxelGrayscale8(0, 1, 2)); + ASSERT_EQ(50, image.GetVoxelGrayscale8(0, 2, 2)); + ASSERT_EQ(75, image.GetVoxelGrayscale8(0, 0, 1)); + ASSERT_EQ(100, image.GetVoxelGrayscale8(0, 1, 1)); + ASSERT_EQ(125, image.GetVoxelGrayscale8(0, 2, 1)); + ASSERT_EQ(150, image.GetVoxelGrayscale8(0, 0, 0)); + ASSERT_EQ(175, image.GetVoxelGrayscale8(0, 1, 0)); + ASSERT_EQ(200, image.GetVoxelGrayscale8(0, 2, 0)); + + // Ensure that "SubvoxelReader" is consistent with "image.GetVoxelGrayscale8()" + float v; + OrthancStone::SubvoxelReader<Orthanc::PixelFormat_Grayscale8, + OrthancStone::ImageInterpolation_Nearest> reader(image); + + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 0.01, 2.01)); ASSERT_FLOAT_EQ(0, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 1.01, 2.01)); ASSERT_FLOAT_EQ(25, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 2.01, 2.01)); ASSERT_FLOAT_EQ(50, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 0.01, 1.01)); ASSERT_FLOAT_EQ(75, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 1.01, 1.01)); ASSERT_FLOAT_EQ(100, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 2.01, 1.01)); ASSERT_FLOAT_EQ(125, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 0.01, 0.01)); ASSERT_FLOAT_EQ(150, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 1.01, 0.01)); ASSERT_FLOAT_EQ(175, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.1, 2.01, 0.01)); ASSERT_FLOAT_EQ(200, v); + + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 2.99)); ASSERT_FLOAT_EQ(0, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 1.99, 2.99)); ASSERT_FLOAT_EQ(25, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 2.99, 2.99)); ASSERT_FLOAT_EQ(50, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 1.99)); ASSERT_FLOAT_EQ(75, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 1.99, 1.99)); ASSERT_FLOAT_EQ(100, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 2.99, 1.99)); ASSERT_FLOAT_EQ(125, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 0.99, 0.99)); ASSERT_FLOAT_EQ(150, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 1.99, 0.99)); ASSERT_FLOAT_EQ(175, v); + ASSERT_TRUE(reader.GetFloatValue(v, 0.99, 2.99, 0.99)); ASSERT_FLOAT_EQ(200, v); + } +} + + TEST(VolumeRendering, Axial) { OrthancStone::CoordinateSystem3D axial(OrthancStone::LinearAlgebra::CreateVector(-0.5, -0.5, 0),