Mercurial > hg > orthanc
diff Core/Images/ImageProcessing.cpp @ 2904:0dd54ee073db
float to integer grayscale conversion
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 30 Oct 2018 10:46:17 +0100 |
parents | e80b38fb22c6 |
children | 7791eac62572 |
line wrap: on
line diff
--- a/Core/Images/ImageProcessing.cpp Tue Oct 23 17:32:56 2018 +0200 +++ b/Core/Images/ImageProcessing.cpp Tue Oct 30 10:46:17 2018 +0100 @@ -53,12 +53,15 @@ const TargetType minValue = std::numeric_limits<TargetType>::min(); const TargetType maxValue = std::numeric_limits<TargetType>::max(); - for (unsigned int y = 0; y < source.GetHeight(); y++) + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { TargetType* t = reinterpret_cast<TargetType*>(target.GetRow(y)); const SourceType* s = reinterpret_cast<const SourceType*>(source.GetConstRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++) + for (unsigned int x = 0; x < width; x++, t++, s++) { if (static_cast<int32_t>(*s) < static_cast<int32_t>(minValue)) { @@ -83,12 +86,15 @@ { assert(sizeof(float) == 4); - for (unsigned int y = 0; y < source.GetHeight(); y++) + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { float* t = reinterpret_cast<float*>(target.GetRow(y)); const SourceType* s = reinterpret_cast<const SourceType*>(source.GetConstRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++) + for (unsigned int x = 0; x < width; x++, t++, s++) { *t = static_cast<float>(*s); } @@ -96,6 +102,30 @@ } + template <PixelFormat TargetFormat> + static void ConvertFloatToGrayscale(ImageAccessor& target, + const ImageAccessor& source) + { + typedef typename PixelTraits<TargetFormat>::PixelType TargetType; + + assert(sizeof(float) == 4); + + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + + for (unsigned int y = 0; y < height; y++) + { + TargetType* q = reinterpret_cast<TargetType*>(target.GetRow(y)); + const float* p = reinterpret_cast<const float*>(source.GetConstRow(y)); + + for (unsigned int x = 0; x < width; x++, p++, q++) + { + PixelTraits<TargetFormat>::FloatToPixel(*q, *p); + } + } + } + + template <typename TargetType> static void ConvertColorToGrayscale(ImageAccessor& target, const ImageAccessor& source) @@ -105,12 +135,15 @@ const TargetType minValue = std::numeric_limits<TargetType>::min(); const TargetType maxValue = std::numeric_limits<TargetType>::max(); - for (unsigned int y = 0; y < source.GetHeight(); y++) + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { TargetType* t = reinterpret_cast<TargetType*>(target.GetRow(y)); const uint8_t* s = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s += 3) + for (unsigned int x = 0; x < width; x++, t++, s += 3) { // Y = 0.2126 R + 0.7152 G + 0.0722 B int32_t v = (2126 * static_cast<int32_t>(s[0]) + @@ -198,9 +231,10 @@ minValue = std::numeric_limits<PixelType>::max(); maxValue = std::numeric_limits<PixelType>::min(); + const unsigned int height = source.GetHeight(); const unsigned int width = source.GetWidth(); - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y)); @@ -233,11 +267,14 @@ const int64_t minValue = std::numeric_limits<PixelType>::min(); const int64_t maxValue = std::numeric_limits<PixelType>::max(); - for (unsigned int y = 0; y < image.GetHeight(); y++) + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); - for (unsigned int x = 0; x < image.GetWidth(); x++, p++) + for (unsigned int x = 0; x < width; x++, p++) { int64_t v = static_cast<int64_t>(*p) + constant; @@ -271,9 +308,11 @@ const int64_t minValue = std::numeric_limits<PixelType>::min(); const int64_t maxValue = std::numeric_limits<PixelType>::max(); - const unsigned int width = image.GetWidth(); - for (unsigned int y = 0; y < image.GetHeight(); y++) + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); @@ -385,6 +424,9 @@ throw OrthancException(ErrorCode_IncompatibleImageSize); } + const unsigned int width = source.GetWidth(); + const unsigned int height = source.GetHeight(); + if (source.GetFormat() == target.GetFormat()) { Copy(target, source); @@ -482,14 +524,15 @@ return; } + if (target.GetFormat() == PixelFormat_Grayscale8 && source.GetFormat() == PixelFormat_RGBA32) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, q++) + for (unsigned int x = 0; x < width; x++, q++) { *q = static_cast<uint8_t>((2126 * static_cast<uint32_t>(p[0]) + 7152 * static_cast<uint32_t>(p[1]) + @@ -504,11 +547,11 @@ if (target.GetFormat() == PixelFormat_Grayscale8 && source.GetFormat() == PixelFormat_BGRA32) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++, q++) + for (unsigned int x = 0; x < width; x++, q++) { *q = static_cast<uint8_t>((2126 * static_cast<uint32_t>(p[2]) + 7152 * static_cast<uint32_t>(p[1]) + @@ -523,11 +566,11 @@ if (target.GetFormat() == PixelFormat_RGB24 && source.GetFormat() == PixelFormat_RGBA32) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[0]; q[1] = p[1]; @@ -543,11 +586,11 @@ if (target.GetFormat() == PixelFormat_RGB24 && source.GetFormat() == PixelFormat_BGRA32) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[2]; q[1] = p[1]; @@ -563,11 +606,11 @@ if (target.GetFormat() == PixelFormat_RGBA32 && source.GetFormat() == PixelFormat_RGB24) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[0]; q[1] = p[1]; @@ -584,11 +627,11 @@ if (target.GetFormat() == PixelFormat_RGB24 && source.GetFormat() == PixelFormat_Grayscale8) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = *p; q[1] = *p; @@ -605,11 +648,11 @@ target.GetFormat() == PixelFormat_BGRA32) && source.GetFormat() == PixelFormat_Grayscale8) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = *p; q[1] = *p; @@ -626,11 +669,11 @@ if (target.GetFormat() == PixelFormat_BGRA32 && source.GetFormat() == PixelFormat_Grayscale16) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { uint8_t value = (*p < 256 ? *p : 255); q[0] = value; @@ -648,11 +691,11 @@ if (target.GetFormat() == PixelFormat_BGRA32 && source.GetFormat() == PixelFormat_SignedGrayscale16) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const int16_t* p = reinterpret_cast<const int16_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { uint8_t value; if (*p < 0) @@ -683,11 +726,11 @@ if (target.GetFormat() == PixelFormat_BGRA32 && source.GetFormat() == PixelFormat_RGB24) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[2]; q[1] = p[1]; @@ -704,11 +747,11 @@ if (target.GetFormat() == PixelFormat_RGB24 && source.GetFormat() == PixelFormat_RGB48) { - for (unsigned int y = 0; y < source.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y)); uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); - for (unsigned int x = 0; x < source.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { q[0] = p[0] >> 8; q[1] = p[1] >> 8; @@ -721,6 +764,20 @@ return; } + if (target.GetFormat() == PixelFormat_Grayscale16 && + source.GetFormat() == PixelFormat_Float32) + { + ConvertFloatToGrayscale<PixelFormat_Grayscale16>(target, source); + return; + } + + if (target.GetFormat() == PixelFormat_Grayscale8 && + source.GetFormat() == PixelFormat_Float32) + { + ConvertFloatToGrayscale<PixelFormat_Grayscale8>(target, source); + return; + } + throw OrthancException(ErrorCode_NotImplemented); } @@ -800,11 +857,14 @@ throw OrthancException(ErrorCode_NotImplemented); } - for (unsigned int y = 0; y < image.GetHeight(); y++) + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + + for (unsigned int y = 0; y < height; y++) { uint8_t* q = reinterpret_cast<uint8_t*>(image.GetRow(y)); - for (unsigned int x = 0; x < image.GetWidth(); x++) + for (unsigned int x = 0; x < width; x++) { for (unsigned int i = 0; i < size; i++) { @@ -1019,15 +1079,18 @@ void ImageProcessing::Invert(ImageAccessor& image) { + const unsigned int width = image.GetWidth(); + const unsigned int height = image.GetHeight(); + switch (image.GetFormat()) { case PixelFormat_Grayscale8: { - for (unsigned int y = 0; y < image.GetHeight(); y++) + for (unsigned int y = 0; y < height; y++) { uint8_t* p = reinterpret_cast<uint8_t*>(image.GetRow(y)); - for (unsigned int x = 0; x < image.GetWidth(); x++, p++) + for (unsigned int x = 0; x < width; x++, p++) { *p = 255 - (*p); }