Mercurial > hg > orthanc
diff OrthancFramework/Sources/Images/ImageProcessing.cpp @ 4065:d6362b2c4b61 framework
export dcmdata in shared library, rounding in convolution tests
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 11 Jun 2020 18:04:28 +0200 |
parents | 55727d85f419 |
children | 259c33759937 |
line wrap: on
line diff
--- a/OrthancFramework/Sources/Images/ImageProcessing.cpp Thu Jun 11 16:40:34 2020 +0200 +++ b/OrthancFramework/Sources/Images/ImageProcessing.cpp Thu Jun 11 18:04:28 2020 +0200 @@ -366,6 +366,7 @@ int64_t v; if (UseRound) { + assert(sizeof(long long) == sizeof(int64_t)); // The "round" operation is very costly v = boost::math::llround(static_cast<float>(*p) * factor); } @@ -442,8 +443,9 @@ *p = minPixelValue; } else if (UseRound) - { + { // The "round" operation is very costly + assert(sizeof(TargetType) < sizeof(int)); *p = static_cast<TargetType>(boost::math::iround(v)); } else @@ -2197,7 +2199,7 @@ // floating-point arithmetics, and an intermediate Float32 // image. The out-of-image values are taken as the border // value. Further optimization is possible. - template <typename RawPixel, unsigned int ChannelsCount> + template <typename RawPixel, unsigned int ChannelsCount, bool UseRound> static void SeparableConvolutionFloat(ImageAccessor& image /* inplace */, const std::vector<float>& horizontal, size_t horizontalAnchor, @@ -2335,7 +2337,15 @@ } else { - *p = static_cast<RawPixel>(accumulator); + if (UseRound) + { + assert(sizeof(RawPixel) < sizeof(int)); + *p = static_cast<RawPixel>(boost::math::iround(accumulator)); + } + else + { + *p = static_cast<RawPixel>(accumulator); + } } } } @@ -2347,7 +2357,8 @@ const std::vector<float>& horizontal, size_t horizontalAnchor, const std::vector<float>& vertical, - size_t verticalAnchor) + size_t verticalAnchor, + bool useRound) { if (horizontal.size() == 0 || vertical.size() == 0 || @@ -2390,13 +2401,29 @@ switch (image.GetFormat()) { case PixelFormat_Grayscale8: - SeparableConvolutionFloat<uint8_t, 1u> - (image, horizontal, horizontalAnchor, vertical, verticalAnchor, normalization); + if (useRound) + { + SeparableConvolutionFloat<uint8_t, 1u, true> + (image, horizontal, horizontalAnchor, vertical, verticalAnchor, normalization); + } + else + { + SeparableConvolutionFloat<uint8_t, 1u, false> + (image, horizontal, horizontalAnchor, vertical, verticalAnchor, normalization); + } break; case PixelFormat_RGB24: - SeparableConvolutionFloat<uint8_t, 3u> - (image, horizontal, horizontalAnchor, vertical, verticalAnchor, normalization); + if (useRound) + { + SeparableConvolutionFloat<uint8_t, 3u, true> + (image, horizontal, horizontalAnchor, vertical, verticalAnchor, normalization); + } + else + { + SeparableConvolutionFloat<uint8_t, 3u, false> + (image, horizontal, horizontalAnchor, vertical, verticalAnchor, normalization); + } break; default: @@ -2405,7 +2432,8 @@ } - void ImageProcessing::SmoothGaussian5x5(ImageAccessor& image) + void ImageProcessing::SmoothGaussian5x5(ImageAccessor& image, + bool useRound) { std::vector<float> kernel(5); kernel[0] = 1; @@ -2414,7 +2442,7 @@ kernel[3] = 4; kernel[4] = 1; - SeparableConvolution(image, kernel, 2, kernel, 2); + SeparableConvolution(image, kernel, 2, kernel, 2, useRound); } @@ -2445,6 +2473,7 @@ unsigned int sw = std::min(static_cast<unsigned int>(boost::math::iround(cw * r)), target.GetWidth()); unsigned int sh = std::min(static_cast<unsigned int>(boost::math::iround(ch * r)), target.GetHeight()); + Image resized(target.GetFormat(), sw, sh, false); //ImageProcessing::SmoothGaussian5x5(source);