Mercurial > hg > orthanc
comparison Core/Images/ImageProcessing.cpp @ 3548:e1ce68692069
ImageProcessing::ApplyWindowing
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Thu, 24 Oct 2019 11:40:02 +0200 |
parents | dabe17e23e23 |
children | 0f5f9a5eed25 |
comparison
equal
deleted
inserted
replaced
3547:dabe17e23e23 | 3548:e1ce68692069 |
---|---|
472 memcpy(target.GetRow(y), source.GetConstRow(y), lineSize); | 472 memcpy(target.GetRow(y), source.GetConstRow(y), lineSize); |
473 } | 473 } |
474 } | 474 } |
475 | 475 |
476 | 476 |
477 void ImageProcessing::ApplyWindowing(ImageAccessor& target, | |
478 const ImageAccessor& source, | |
479 float windowCenter, | |
480 float windowWidth, | |
481 Orthanc::PhotometricInterpretation sourcePhotometricInterpretation) | |
482 { | |
483 if (source.GetFormat() != Orthanc::PixelFormat_Float32) | |
484 { | |
485 throw OrthancException(ErrorCode_NotImplemented); | |
486 } | |
487 | |
488 if (sourcePhotometricInterpretation != Orthanc::PhotometricInterpretation_Monochrome1 | |
489 && sourcePhotometricInterpretation != Orthanc::PhotometricInterpretation_Monochrome2) | |
490 { | |
491 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
492 } | |
493 | |
494 if (target.GetWidth() != source.GetWidth() || | |
495 target.GetHeight() != source.GetHeight()) | |
496 { | |
497 throw OrthancException(ErrorCode_IncompatibleImageSize); | |
498 } | |
499 | |
500 unsigned int targetBytesPerPixels = target.GetBytesPerPixel(); | |
501 unsigned int targetChannelsPerPixels = 0; | |
502 switch (target.GetFormat()) | |
503 { | |
504 case Orthanc::PixelFormat_Grayscale8: | |
505 targetChannelsPerPixels = 1; | |
506 break; | |
507 case Orthanc::PixelFormat_RGBA32: | |
508 case Orthanc::PixelFormat_BGRA32: | |
509 case Orthanc::PixelFormat_RGB24: | |
510 targetChannelsPerPixels = 3; | |
511 break; | |
512 default: | |
513 throw OrthancException(ErrorCode_NotImplemented); | |
514 } | |
515 | |
516 const float a = windowCenter - windowWidth / 2.0f; | |
517 const float slope = 256.0f / windowWidth; | |
518 bool isInverted = sourcePhotometricInterpretation == Orthanc::PhotometricInterpretation_Monochrome1; | |
519 | |
520 const unsigned int width = source.GetWidth(); | |
521 const unsigned int height = source.GetHeight(); | |
522 | |
523 assert(sizeof(float) == 4); | |
524 | |
525 for (unsigned int y = 0; y < height; y++) | |
526 { | |
527 const float* p = reinterpret_cast<const float*>(source.GetConstRow(y)); | |
528 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); | |
529 | |
530 for (unsigned int x = 0; x < width; x++) | |
531 { | |
532 float v = (*p - a) * slope; | |
533 if (v <= 0) | |
534 { | |
535 v = 0; | |
536 } | |
537 else if (v >= 255) | |
538 { | |
539 v = 255; | |
540 } | |
541 | |
542 uint8_t vv = static_cast<uint8_t>(v); | |
543 | |
544 if (isInverted) | |
545 { | |
546 vv = 255 - vv; | |
547 } | |
548 | |
549 for (unsigned int c = 0; c < targetChannelsPerPixels; c++) | |
550 { | |
551 q[c] = vv; | |
552 } | |
553 | |
554 p++; | |
555 q += targetBytesPerPixels; | |
556 } | |
557 } | |
558 | |
559 } | |
560 | |
561 | |
477 void ImageProcessing::Convert(ImageAccessor& target, | 562 void ImageProcessing::Convert(ImageAccessor& target, |
478 const ImageAccessor& source) | 563 const ImageAccessor& source) |
479 { | 564 { |
480 if (target.GetWidth() != source.GetWidth() || | 565 if (target.GetWidth() != source.GetWidth() || |
481 target.GetHeight() != source.GetHeight()) | 566 target.GetHeight() != source.GetHeight()) |
966 } | 1051 } |
967 } | 1052 } |
968 } | 1053 } |
969 | 1054 |
970 void ImageProcessing::Set(ImageAccessor& image, | 1055 void ImageProcessing::Set(ImageAccessor& image, |
971 uint8_t red, | 1056 uint8_t red, |
972 uint8_t green, | 1057 uint8_t green, |
973 uint8_t blue, | 1058 uint8_t blue, |
974 ImageAccessor& alpha) | 1059 ImageAccessor& alpha) |
975 { | 1060 { |
976 uint8_t p[4]; | 1061 uint8_t p[4]; |
977 | 1062 |
978 if (alpha.GetWidth() != image.GetWidth() || alpha.GetHeight() != image.GetHeight()) | 1063 if (alpha.GetWidth() != image.GetWidth() || alpha.GetHeight() != image.GetHeight()) |
979 { | 1064 { |
1848 source.GetHeight() == target.GetHeight()) | 1933 source.GetHeight() == target.GetHeight()) |
1849 { | 1934 { |
1850 Copy(target, source); | 1935 Copy(target, source); |
1851 return; | 1936 return; |
1852 } | 1937 } |
1853 | 1938 |
1854 switch (source.GetFormat()) | 1939 switch (source.GetFormat()) |
1855 { | 1940 { |
1856 case PixelFormat_Grayscale8: | 1941 case PixelFormat_Grayscale8: |
1857 ResizeInternal<PixelFormat_Grayscale8>(target, source); | 1942 ResizeInternal<PixelFormat_Grayscale8>(target, source); |
1943 break; | |
1944 | |
1945 case PixelFormat_Float32: | |
1946 ResizeInternal<PixelFormat_Float32>(target, source); | |
1858 break; | 1947 break; |
1859 | 1948 |
1860 case PixelFormat_RGB24: | 1949 case PixelFormat_RGB24: |
1861 ResizeInternal<PixelFormat_RGB24>(target, source); | 1950 ResizeInternal<PixelFormat_RGB24>(target, source); |
1862 break; | 1951 break; |