Mercurial > hg > orthanc-stone
comparison UnitTestsSources/VolumeRenderingTests.cpp @ 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 |
comparison
equal
deleted
inserted
replaced
1780:b7c9fd1e9fb0 | 1781:bf4b15b059ea |
---|---|
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 **/ | 19 **/ |
20 | 20 |
21 | 21 |
22 #include "../OrthancStone/Sources/Scene2D/CairoCompositor.h" | 22 #include "../OrthancStone/Sources/Scene2D/CairoCompositor.h" |
23 #include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h" | |
23 #include "../OrthancStone/Sources/Scene2D/CopyStyleConfigurator.h" | 24 #include "../OrthancStone/Sources/Scene2D/CopyStyleConfigurator.h" |
24 #include "../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h" | |
25 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.h" | 25 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageMPRSlicer.h" |
26 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageReslicer.h" | 26 #include "../OrthancStone/Sources/Volumes/DicomVolumeImageReslicer.h" |
27 | 27 |
28 #include <Images/ImageProcessing.h> | 28 #include <Images/ImageProcessing.h> |
29 #include <Images/ImageTraits.h> | 29 #include <Images/ImageTraits.h> |
92 Orthanc::ImageAccessor region; | 92 Orthanc::ImageAccessor region; |
93 image.GetRegion(region, x, y, width, height); | 93 image.GetRegion(region, x, y, width, height); |
94 return IsConstImage(value, region); | 94 return IsConstImage(value, region); |
95 } | 95 } |
96 | 96 |
97 | |
98 static bool IsConstImageWithExclusion(float value, | |
99 const Orthanc::ImageAccessor& image, | |
100 unsigned int exclusionX, | |
101 unsigned int exclusionY, | |
102 unsigned int exclusionWidth, | |
103 unsigned int exclusionHeight) | |
104 { | |
105 for (unsigned int y = 0; y < image.GetHeight(); y++) | |
106 { | |
107 for (unsigned int x = 0; x < image.GetWidth(); x++) | |
108 { | |
109 if ((x < exclusionX || | |
110 y < exclusionY || | |
111 x >= exclusionX + exclusionWidth || | |
112 y >= exclusionY + exclusionHeight) && | |
113 !OrthancStone::LinearAlgebra::IsNear(value, GetPixelValue(image, x, y))) | |
114 { | |
115 return false; | |
116 } | |
117 } | |
118 } | |
119 | |
120 return true; | |
121 } | |
122 | |
123 | |
124 static bool AreSameImages(const Orthanc::ImageAccessor& image1, | |
125 const Orthanc::ImageAccessor& image2) | |
126 { | |
127 if (image1.GetWidth() != image2.GetWidth() || | |
128 image1.GetHeight() != image2.GetHeight()) | |
129 { | |
130 return false; | |
131 } | |
132 | |
133 for (unsigned int y = 0; y < image1.GetHeight(); y++) | |
134 { | |
135 for (unsigned int x = 0; x < image1.GetWidth(); x++) | |
136 { | |
137 if (!OrthancStone::LinearAlgebra::IsNear(GetPixelValue(image1, x, y), | |
138 GetPixelValue(image2, x, y))) | |
139 { | |
140 return false; | |
141 } | |
142 } | |
143 } | |
144 | |
145 return true; | |
146 } | |
147 | |
97 | 148 |
98 static void Assign3x3Pattern(Orthanc::ImageAccessor& image) | 149 static void Assign3x3Pattern(Orthanc::ImageAccessor& image) |
99 { | 150 { |
100 if (image.GetFormat() == Orthanc::PixelFormat_Grayscale8 && | 151 if (image.GetFormat() == Orthanc::PixelFormat_Grayscale8 && |
101 image.GetWidth() == 3 && | 152 image.GetWidth() == 3 && |
427 ASSERT_TRUE(IsConstRegion(0.0f, *rendered, 0, 0, 36, 3)); | 478 ASSERT_TRUE(IsConstRegion(0.0f, *rendered, 0, 0, 36, 3)); |
428 ASSERT_TRUE(IsConstRegion(255.0f, *rendered, 0, 3, 36, 24)); | 479 ASSERT_TRUE(IsConstRegion(255.0f, *rendered, 0, 3, 36, 24)); |
429 ASSERT_TRUE(IsConstRegion(0.0f, *rendered, 0, 27, 36, 3)); | 480 ASSERT_TRUE(IsConstRegion(0.0f, *rendered, 0, 27, 36, 3)); |
430 } | 481 } |
431 } | 482 } |
483 | |
484 | |
485 TEST(VolumeRendering, FlipAxial) | |
486 { | |
487 double x = 2; | |
488 double y = 1; | |
489 OrthancStone::CoordinateSystem3D axial(OrthancStone::LinearAlgebra::CreateVector(x, y, 0), | |
490 OrthancStone::LinearAlgebra::CreateVector(1, 0, 0), | |
491 OrthancStone::LinearAlgebra::CreateVector(0, 1, 0)); | |
492 | |
493 Orthanc::Image pattern(Orthanc::PixelFormat_Grayscale8, 3, 3, false); | |
494 Assign3x3Pattern(pattern); | |
495 | |
496 Orthanc::Image patternX(Orthanc::PixelFormat_Grayscale8, 3, 3, false); | |
497 Assign3x3Pattern(patternX); | |
498 Orthanc::ImageProcessing::FlipX(patternX); | |
499 | |
500 Orthanc::Image patternY(Orthanc::PixelFormat_Grayscale8, 3, 3, false); | |
501 Assign3x3Pattern(patternY); | |
502 Orthanc::ImageProcessing::FlipY(patternY); | |
503 | |
504 Orthanc::Image patternXY(Orthanc::PixelFormat_Grayscale8, 3, 3, false); | |
505 Assign3x3Pattern(patternXY); | |
506 Orthanc::ImageProcessing::FlipX(patternXY); | |
507 Orthanc::ImageProcessing::FlipY(patternXY); | |
508 | |
509 for (unsigned int mode = 0; mode < 2; mode++) | |
510 { | |
511 { | |
512 OrthancStone::CoordinateSystem3D cuttingPlane(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0), | |
513 OrthancStone::LinearAlgebra::CreateVector(1, 0, 0), | |
514 OrthancStone::LinearAlgebra::CreateVector(0, 1, 0)); | |
515 | |
516 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer(Slice3x3x1Pattern(axial, cuttingPlane, static_cast<SlicerType>(mode))); | |
517 ASSERT_TRUE(AreSameImages(layer->GetTexture(), pattern)); | |
518 | |
519 OrthancStone::Extent2D extent; | |
520 layer->GetBoundingBox(extent); | |
521 ASSERT_FLOAT_EQ(x - 0.5, extent.GetX1()); | |
522 ASSERT_FLOAT_EQ(y - 0.5, extent.GetY1()); | |
523 ASSERT_FLOAT_EQ(x + 2.5, extent.GetX2()); | |
524 ASSERT_FLOAT_EQ(y + 2.5, extent.GetY2()); | |
525 | |
526 std::unique_ptr<Orthanc::ImageAccessor> rendered(Render(layer.release(), 15, 15)); | |
527 ASSERT_TRUE(IsConstImageWithExclusion(0.0f, *rendered, 9, 8, 3, 3)); | |
528 | |
529 Orthanc::ImageAccessor p; | |
530 rendered->GetRegion(p, 9, 8, 3, 3); | |
531 ASSERT_TRUE(AreSameImages(p, pattern)); | |
532 } | |
533 | |
534 { | |
535 OrthancStone::CoordinateSystem3D cuttingPlane(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0), | |
536 OrthancStone::LinearAlgebra::CreateVector(-1, 0, 0), | |
537 OrthancStone::LinearAlgebra::CreateVector(0, 1, 0)); | |
538 | |
539 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer(Slice3x3x1Pattern(axial, cuttingPlane, static_cast<SlicerType>(mode))); | |
540 if (mode == 1) | |
541 { | |
542 // Reslicer directly flips the pixels of the texture | |
543 ASSERT_TRUE(AreSameImages(layer->GetTexture(), patternX)); | |
544 } | |
545 else | |
546 { | |
547 // MPR slicer uses "TextureBaseSceneLayer::SetTransform()" to flip | |
548 ASSERT_TRUE(AreSameImages(layer->GetTexture(), pattern)); | |
549 } | |
550 | |
551 OrthancStone::Extent2D extent; | |
552 layer->GetBoundingBox(extent); | |
553 ASSERT_FLOAT_EQ(-(x + 2.5), extent.GetX1()); | |
554 ASSERT_FLOAT_EQ(y - 0.5, extent.GetY1()); | |
555 ASSERT_FLOAT_EQ(-(x - 0.5), extent.GetX2()); | |
556 ASSERT_FLOAT_EQ(y + 2.5, extent.GetY2()); | |
557 | |
558 std::unique_ptr<Orthanc::ImageAccessor> rendered(Render(layer.release(), 15, 15)); | |
559 ASSERT_TRUE(IsConstImageWithExclusion(0.0f, *rendered, 3, 8, 3, 3)); | |
560 | |
561 Orthanc::ImageAccessor p; | |
562 rendered->GetRegion(p, 3, 8, 3, 3); | |
563 ASSERT_TRUE(AreSameImages(p, patternX)); | |
564 } | |
565 | |
566 { | |
567 OrthancStone::CoordinateSystem3D cuttingPlane(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0), | |
568 OrthancStone::LinearAlgebra::CreateVector(1, 0, 0), | |
569 OrthancStone::LinearAlgebra::CreateVector(0, -1, 0)); | |
570 | |
571 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer(Slice3x3x1Pattern(axial, cuttingPlane, static_cast<SlicerType>(mode))); | |
572 if (mode == 1) | |
573 { | |
574 ASSERT_TRUE(AreSameImages(layer->GetTexture(), patternY)); | |
575 } | |
576 else | |
577 { | |
578 ASSERT_TRUE(AreSameImages(layer->GetTexture(), pattern)); | |
579 } | |
580 | |
581 OrthancStone::Extent2D extent; | |
582 layer->GetBoundingBox(extent); | |
583 ASSERT_FLOAT_EQ(x - 0.5, extent.GetX1()); | |
584 ASSERT_FLOAT_EQ(-(y + 2.5), extent.GetY1()); | |
585 ASSERT_FLOAT_EQ(x + 2.5, extent.GetX2()); | |
586 ASSERT_FLOAT_EQ(-(y - 0.5), extent.GetY2()); | |
587 | |
588 std::unique_ptr<Orthanc::ImageAccessor> rendered(Render(layer.release(), 15, 15)); | |
589 ASSERT_TRUE(IsConstImageWithExclusion(0.0f, *rendered, 9, 4, 3, 3)); | |
590 | |
591 Orthanc::ImageAccessor p; | |
592 rendered->GetRegion(p, 9, 4, 3, 3); | |
593 ASSERT_TRUE(AreSameImages(p, patternY)); | |
594 } | |
595 | |
596 { | |
597 OrthancStone::CoordinateSystem3D cuttingPlane(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0), | |
598 OrthancStone::LinearAlgebra::CreateVector(-1, 0, 0), | |
599 OrthancStone::LinearAlgebra::CreateVector(0, -1, 0)); | |
600 | |
601 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer(Slice3x3x1Pattern(axial, cuttingPlane, static_cast<SlicerType>(mode))); | |
602 if (mode == 1) | |
603 { | |
604 ASSERT_TRUE(AreSameImages(layer->GetTexture(), patternXY)); | |
605 } | |
606 else | |
607 { | |
608 ASSERT_TRUE(AreSameImages(layer->GetTexture(), pattern)); | |
609 } | |
610 | |
611 OrthancStone::Extent2D extent; | |
612 layer->GetBoundingBox(extent); | |
613 ASSERT_FLOAT_EQ(-(x + 2.5), extent.GetX1()); | |
614 ASSERT_FLOAT_EQ(-(y + 2.5), extent.GetY1()); | |
615 ASSERT_FLOAT_EQ(-(x - 0.5), extent.GetX2()); | |
616 ASSERT_FLOAT_EQ(-(y - 0.5), extent.GetY2()); | |
617 | |
618 std::unique_ptr<Orthanc::ImageAccessor> rendered(Render(layer.release(), 15, 15)); | |
619 ASSERT_TRUE(IsConstImageWithExclusion(0.0f, *rendered, 3, 4, 3, 3)); | |
620 | |
621 Orthanc::ImageAccessor p; | |
622 rendered->GetRegion(p, 3, 4, 3, 3); | |
623 ASSERT_TRUE(AreSameImages(p, patternXY)); | |
624 } | |
625 } | |
626 } |