Mercurial > hg > orthanc
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)); + } + } +}