changeset 4081:259c33759937 framework

integration mainline->framework
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 22 Jun 2020 19:04:45 +0200
parents c5c41f66ec29 (current diff) f18eaade6153 (diff)
children 26efd0404d97
files OrthancFramework/Sources/Images/ImageProcessing.cpp OrthancFramework/Sources/Images/ImageProcessing.h OrthancFramework/UnitTestsSources/ImageProcessingTests.cpp
diffstat 3 files changed, 90 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Sources/Images/ImageProcessing.cpp	Mon Jun 22 15:10:03 2020 +0200
+++ b/OrthancFramework/Sources/Images/ImageProcessing.cpp	Mon Jun 22 19:04:45 2020 +0200
@@ -393,7 +393,8 @@
 
 
   // Computes "a * x + b" at each pixel => Note that this is not the
-  // same convention as in "ShiftScale()"
+  // same convention as in "ShiftScale()", but it is the convention of
+  // "ShiftScale2()"
   template <typename TargetType,
             typename SourceType,
             bool UseRound,
@@ -1375,15 +1376,14 @@
   }
 
 
-  void ImageProcessing::ShiftScale(ImageAccessor& image,
-                                   float offset,
-                                   float scaling,
-                                   bool useRound)
+  void ImageProcessing::ShiftScale2(ImageAccessor& image,
+                                    float offset,
+                                    float scaling,
+                                    bool useRound)
   {
-    // Rewrite "(x + offset) * scaling" as "a * x + b"
-
+    // We compute "a * x + b"
     const float a = scaling;
-    const float b = offset * scaling;
+    const float b = offset;
     
     switch (image.GetFormat())
     {
@@ -1438,16 +1438,15 @@
   }
 
 
-  void ImageProcessing::ShiftScale(ImageAccessor& target,
-                                   const ImageAccessor& source,
-                                   float offset,
-                                   float scaling,
-                                   bool useRound)
+  void ImageProcessing::ShiftScale2(ImageAccessor& target,
+                                    const ImageAccessor& source,
+                                    float offset,
+                                    float scaling,
+                                    bool useRound)
   {
-    // Rewrite "(x + offset) * scaling" as "a * x + b"
-
+    // We compute "a * x + b"
     const float a = scaling;
-    const float b = offset * scaling;
+    const float b = offset;
     
     switch (target.GetFormat())
     {
@@ -1478,6 +1477,34 @@
   }
 
 
+  void ImageProcessing::ShiftScale(ImageAccessor& image,
+                                   float offset,
+                                   float scaling,
+                                   bool useRound)
+  {
+    // Rewrite "(x + offset) * scaling" as "a * x + b"
+
+    const float a = scaling;
+    const float b = offset * scaling;
+    ShiftScale2(image, b, a, useRound);
+  }
+
+
+  void ImageProcessing::ShiftScale(ImageAccessor& target,
+                                   const ImageAccessor& source,
+                                   float offset,
+                                   float scaling,
+                                   bool useRound)
+  {
+    // Rewrite "(x + offset) * scaling" as "a * x + b"
+
+    const float a = scaling;
+    const float b = offset * scaling;
+    ShiftScale2(target, source, b, a, useRound);
+  }
+
+
+
   void ImageProcessing::Invert(ImageAccessor& image, int64_t maxValue)
   {
     const unsigned int width = image.GetWidth();
--- a/OrthancFramework/Sources/Images/ImageProcessing.h	Mon Jun 22 15:10:03 2020 +0200
+++ b/OrthancFramework/Sources/Images/ImageProcessing.h	Mon Jun 22 19:04:45 2020 +0200
@@ -145,6 +145,18 @@
                            float scaling,
                            bool useRound);
 
+    // Computes "x * scaling + offset" inplace. "useRound" is expensive.
+    static void ShiftScale2(ImageAccessor& image,
+                            float offset,
+                            float scaling,
+                            bool useRound);
+
+    static void ShiftScale2(ImageAccessor& target,
+                            const ImageAccessor& source,
+                            float offset,
+                            float scaling,
+                            bool useRound);
+
     static void Invert(ImageAccessor& image);
 
     static void Invert(ImageAccessor& image, int64_t maxValue);
--- a/OrthancFramework/UnitTestsSources/ImageProcessingTests.cpp	Mon Jun 22 15:10:03 2020 +0200
+++ b/OrthancFramework/UnitTestsSources/ImageProcessingTests.cpp	Mon Jun 22 19:04:45 2020 +0200
@@ -1020,3 +1020,38 @@
   ASSERT_TRUE(TestSignedGrayscale16Pixel(image, 3, 0, -82));
   ASSERT_TRUE(TestSignedGrayscale16Pixel(image, 4, 0, 2736));
 }
+
+
+TEST(ImageProcessing, ShiftScale2)
+{
+  std::vector<float> va;
+  va.push_back(0);
+  va.push_back(-10);
+  va.push_back(5);
+  
+  std::vector<float> vb;
+  vb.push_back(0);
+  vb.push_back(-42);
+  vb.push_back(42);
+
+  Image source(PixelFormat_Float32, 1, 1, false);
+  ImageTraits<PixelFormat_Float32>::SetFloatPixel(source, 10, 0, 0);
+  
+  for (std::vector<float>::const_iterator a = va.begin(); a != va.end(); ++a)
+  {
+    for (std::vector<float>::const_iterator b = vb.begin(); b != vb.end(); ++b)
+    {
+      Image target(PixelFormat_Float32, 1, 1, false);
+
+      ImageProcessing::Copy(target, source);
+      ImageProcessing::ShiftScale2(target, *b, *a, false);
+      ASSERT_FLOAT_EQ((*a) * 10.0f + (*b),
+                      ImageTraits<PixelFormat_Float32>::GetFloatPixel(target, 0, 0));
+
+      ImageProcessing::Copy(target, source);
+      ImageProcessing::ShiftScale(target, *b, *a, false);
+      ASSERT_FLOAT_EQ((*a) * (10.0f + (*b)),
+                      ImageTraits<PixelFormat_Float32>::GetFloatPixel(target, 0, 0));
+    }
+  }
+}