Mercurial > hg > orthanc-stone
diff Framework/Volumes/ImageBuffer3D.cpp @ 119:ba83e38cf3ff wasm
rendering of rt-dose
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 02 Oct 2017 22:01:41 +0200 |
parents | 2eca030792aa |
children | e2fe9352f240 |
line wrap: on
line diff
--- a/Framework/Volumes/ImageBuffer3D.cpp Mon Oct 02 14:31:26 2017 +0200 +++ b/Framework/Volumes/ImageBuffer3D.cpp Mon Oct 02 22:01:41 2017 +0200 @@ -112,12 +112,15 @@ ImageBuffer3D::ImageBuffer3D(Orthanc::PixelFormat format, unsigned int width, unsigned int height, - unsigned int depth) : + unsigned int depth, + bool computeRange) : image_(format, width, height * depth, false), format_(format), width_(width), height_(height), - depth_(depth) + depth_(depth), + computeRange_(computeRange), + hasRange_(false) { GeometryToolbox::AssignVector(voxelDimensions_, 1, 1, 1); @@ -265,6 +268,91 @@ } + void ImageBuffer3D::ExtendImageRange(const Orthanc::ImageAccessor& slice) + { + if (!computeRange_ || + slice.GetWidth() == 0 || + slice.GetHeight() == 0) + { + return; + } + + float sliceMin, sliceMax; + + switch (slice.GetFormat()) + { + case Orthanc::PixelFormat_Grayscale8: + case Orthanc::PixelFormat_Grayscale16: + case Orthanc::PixelFormat_Grayscale32: + case Orthanc::PixelFormat_SignedGrayscale16: + { + int64_t a, b; + Orthanc::ImageProcessing::GetMinMaxIntegerValue(a, b, slice); + sliceMin = static_cast<float>(a); + sliceMax = static_cast<float>(b); + break; + } + + case Orthanc::PixelFormat_Float32: + Orthanc::ImageProcessing::GetMinMaxFloatValue(sliceMin, sliceMax, slice); + break; + + default: + return; + } + + if (hasRange_) + { + minValue_ = std::min(minValue_, sliceMin); + maxValue_ = std::max(maxValue_, sliceMax); + } + else + { + hasRange_ = true; + minValue_ = sliceMin; + maxValue_ = sliceMax; + } + } + + + bool ImageBuffer3D::GetRange(float& minValue, + float& maxValue) const + { + if (hasRange_) + { + minValue = minValue_; + maxValue = maxValue_; + return true; + } + else + { + return false; + } + } + + + bool ImageBuffer3D::FitWindowingToRange(RenderStyle& style, + const DicomFrameConverter& converter) const + { + if (hasRange_) + { + style.windowing_ = ImageWindowing_Custom; + style.customWindowCenter_ = converter.Apply((minValue_ + maxValue_) / 2.0); + style.customWindowWidth_ = converter.Apply(maxValue_ - minValue_); + + if (style.customWindowWidth_ > 1) + { + return true; + } + } + + style.windowing_ = ImageWindowing_Custom; + style.customWindowCenter_ = 128.0; + style.customWindowWidth_ = 256.0; + return false; + } + + ImageBuffer3D::SliceReader::SliceReader(ImageBuffer3D& that, VolumeProjection projection, unsigned int slice) @@ -299,6 +387,10 @@ // TODO throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); } + + // Update the dynamic range of the underlying image, if + // "computeRange_" is set to true + that_.ExtendImageRange(accessor_); } } @@ -306,7 +398,8 @@ ImageBuffer3D::SliceWriter::SliceWriter(ImageBuffer3D& that, VolumeProjection projection, unsigned int slice) : - modified_(false) + that_(that), + modified_(false) { switch (projection) {