Mercurial > hg > orthanc-stone
changeset 1677:51bab5188a13
start multiple preset windowings
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 23 Nov 2020 19:24:18 +0100 |
parents | 5e76d5e8167a |
children | 1393e3393a0b |
files | Applications/StoneWebViewer/WebApplication/app.js Applications/StoneWebViewer/WebApplication/index.html Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Sources/Loaders/SeriesFramesLoader.cpp OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp OrthancStone/Sources/Toolbox/DicomInstanceParameters.h |
diffstat | 6 files changed, 113 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebApplication/app.js Mon Nov 23 18:49:42 2020 +0100 +++ b/Applications/StoneWebViewer/WebApplication/app.js Mon Nov 23 19:24:18 2020 +0100 @@ -623,10 +623,10 @@ } }, - SetDefaultWindowing: function() { + SetPresetWindowing: function() { var canvas = this.GetActiveCanvas(); if (canvas != '') { - stone.SetDefaultWindowing(canvas); + stone.SetPresetWindowing(canvas); } },
--- a/Applications/StoneWebViewer/WebApplication/index.html Mon Nov 23 18:49:42 2020 +0100 +++ b/Applications/StoneWebViewer/WebApplication/index.html Mon Nov 23 19:24:18 2020 +0100 @@ -478,8 +478,8 @@ <ul class="wvToolbar__windowingPresetList"> <li class="wvToolbar__windowingPresetListItem"> - <a href="#" onclick="app.SetDefaultWindowing()"> - Default + <a href="#" onclick="app.SetPresetWindowing()"> + Preset </a> </li> <li class="wvToolbar__windowingPresetListItem">
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Mon Nov 23 18:49:42 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Mon Nov 23 19:24:18 2020 +0100 @@ -1102,20 +1102,21 @@ { OrthancStone::DicomInstanceParameters params(dicom); - if (params.HasDefaultWindowing()) + // TODO - WINDOWING + if (params.GetPresetWindowingsCount() > 0) { - GetViewport().defaultWindowingCenter_ = params.GetDefaultWindowingCenter(); - GetViewport().defaultWindowingWidth_ = params.GetDefaultWindowingWidth(); - LOG(INFO) << "Default windowing: " << params.GetDefaultWindowingCenter() - << "," << params.GetDefaultWindowingWidth(); - - GetViewport().windowingCenter_ = params.GetDefaultWindowingCenter(); - GetViewport().windowingWidth_ = params.GetDefaultWindowingWidth(); + GetViewport().presetWindowingCenter_ = params.GetPresetWindowingCenter(0); + GetViewport().presetWindowingWidth_ = params.GetPresetWindowingWidth(0); + LOG(INFO) << "Preset windowing: " << params.GetPresetWindowingCenter(0) + << "," << params.GetPresetWindowingWidth(0); + + GetViewport().windowingCenter_ = params.GetPresetWindowingCenter(0); + GetViewport().windowingWidth_ = params.GetPresetWindowingWidth(0); } else { - LOG(INFO) << "No default windowing"; - GetViewport().ResetDefaultWindowing(); + LOG(INFO) << "No preset windowing"; + GetViewport().ResetPresetWindowing(); } } @@ -1361,8 +1362,8 @@ std::unique_ptr<SeriesCursor> cursor_; float windowingCenter_; float windowingWidth_; - float defaultWindowingCenter_; - float defaultWindowingWidth_; + float presetWindowingCenter_; + float presetWindowingWidth_; unsigned int cineRate_; bool inverted_; bool flipX_; @@ -1410,13 +1411,13 @@ } - void ResetDefaultWindowing() + void ResetPresetWindowing() { - defaultWindowingCenter_ = 128; - defaultWindowingWidth_ = 256; - - windowingCenter_ = defaultWindowingCenter_; - windowingWidth_ = defaultWindowingWidth_; + presetWindowingCenter_ = 128; + presetWindowingWidth_ = 256; + + windowingCenter_ = presetWindowingCenter_; + windowingWidth_ = presetWindowingWidth_; inverted_ = false; } @@ -1789,7 +1790,7 @@ emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, OnKey); emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, OnKey); - ResetDefaultWindowing(); + ResetPresetWindowing(); } static EM_BOOL OnKey(int eventType, @@ -1897,7 +1898,7 @@ LOG(INFO) << "Number of frames in series: " << frames_->GetFramesCount(); - ResetDefaultWindowing(); + ResetPresetWindowing(); ClearViewport(); prefetchQueue_.clear(); @@ -2126,9 +2127,9 @@ } - void SetDefaultWindowing() + void SetPresetWindowing() { - SetWindowing(defaultWindowingCenter_, defaultWindowingWidth_); + SetWindowing(presetWindowingCenter_, presetWindowingWidth_); } void SetWindowing(float windowingCenter, @@ -2817,11 +2818,11 @@ EMSCRIPTEN_KEEPALIVE - void SetDefaultWindowing(const char* canvas) + void SetPresetWindowing(const char* canvas) { try { - GetViewport(canvas)->SetDefaultWindowing(); + GetViewport(canvas)->SetPresetWindowing(); } EXTERN_CATCH_EXCEPTIONS; }
--- a/OrthancStone/Sources/Loaders/SeriesFramesLoader.cpp Mon Nov 23 18:49:42 2020 +0100 +++ b/OrthancStone/Sources/Loaders/SeriesFramesLoader.cpp Mon Nov 23 19:24:18 2020 +0100 @@ -307,6 +307,16 @@ } + static void GetBounds(float& low, + float& high, + double center, // in + double width) // in + { + low = static_cast<float>(center - width / 2.0); + high = static_cast<float>(center + width / 2.0); + } + + void SeriesFramesLoader::GetPreviewWindowing(float& center, float& width, size_t index) const @@ -314,11 +324,39 @@ const Orthanc::DicomMap& instance = frames_.GetInstance(index); const DicomInstanceParameters& parameters = frames_.GetInstanceParameters(index); - if (parameters.HasDefaultWindowing()) + size_t s = parameters.GetPresetWindowingsCount(); + + if (s > 0) { - // TODO - Handle multiple presets (take the largest width) - center = parameters.GetDefaultWindowingCenter(); - width = parameters.GetDefaultWindowingWidth(); + // Use the largest windowing given all the preset windowings + // that are available in the DICOM tags + float low, high; + GetBounds(low, high, parameters.GetPresetWindowingCenter(0), + parameters.GetPresetWindowingWidth(0)); + + for (size_t i = 1; i < s; i++) + { + float a, b; + GetBounds(a, b, parameters.GetPresetWindowingCenter(i), + parameters.GetPresetWindowingWidth(i)); + low = std::min(low, a); + high = std::max(high, b); + } + + assert(low <= high); + + if (LinearAlgebra::IsNear(low, high)) + { + // Cannot infer a suitable windowing from the available tags + center = 128.0f; + width = 256.0f; + } + else + { + center = (low + high) / 2.0f; + width = (high - low); + printf(">> %f %f\n", center, width); + } } else {
--- a/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp Mon Nov 23 18:49:42 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp Mon Nov 23 19:24:18 2020 +0100 @@ -180,22 +180,28 @@ } } - Vector c, w; - if (LinearAlgebra::ParseVector(c, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) && - LinearAlgebra::ParseVector(w, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH) && - c.size() > 0 && - w.size() > 0) + bool ok = false; + + if (LinearAlgebra::ParseVector(presetWindowingCenters_, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) && + LinearAlgebra::ParseVector(presetWindowingWidths_, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH)) { - hasDefaultWindowing_ = true; - defaultWindowingCenter_ = static_cast<float>(c[0]); - defaultWindowingWidth_ = static_cast<float>(w[0]); + if (presetWindowingCenters_.size() == presetWindowingWidths_.size()) + { + ok = true; + } + else + { + LOG(ERROR) << "Mismatch in the number of preset windowing widths/centers, ignoring this"; + ok = false; + } } - else + + if (!ok) { - hasDefaultWindowing_ = false; - defaultWindowingCenter_ = 0; - defaultWindowingWidth_ = 0; - } + // Don't use "Vector::clear()", as it has not the same meaning as "std::vector::clear()" + presetWindowingCenters_.resize(0); + presetWindowingWidths_.resize(0); + } // This computes the "IndexInSeries" metadata from Orthanc (check // out "Orthanc::ServerIndex::Store()") @@ -391,34 +397,39 @@ } - float DicomInstanceParameters::GetDefaultWindowingCenter() const + size_t DicomInstanceParameters::GetPresetWindowingsCount() const { - if (data_.hasDefaultWindowing_) + assert(data_.presetWindowingCenters_.size() == data_.presetWindowingWidths_.size()); + return data_.presetWindowingCenters_.size(); + } + + + float DicomInstanceParameters::GetPresetWindowingCenter(size_t i) const + { + if (i < GetPresetWindowingsCount()) { - return data_.defaultWindowingCenter_; + return static_cast<float>(data_.presetWindowingCenters_[i]); } else { - LOG(ERROR) << "DicomInstanceParameters::GetDefaultWindowingCenter(): no default windowing"; - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } } - float DicomInstanceParameters::GetDefaultWindowingWidth() const + float DicomInstanceParameters::GetPresetWindowingWidth(size_t i) const { - if (data_.hasDefaultWindowing_) + if (i < GetPresetWindowingsCount()) { - return data_.defaultWindowingWidth_; + return static_cast<float>(data_.presetWindowingWidths_[i]); } else { - LOG(ERROR) << "DicomInstanceParameters::GetDefaultWindowingWidth(): no default windowing"; - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } } - + Orthanc::ImageAccessor* DicomInstanceParameters::ConvertToFloat(const Orthanc::ImageAccessor& pixelData) const { std::unique_ptr<Orthanc::Image> converted(new Orthanc::Image(Orthanc::PixelFormat_Float32, @@ -483,10 +494,9 @@ texture.reset(new FloatTextureSceneLayer(*converted)); } - if (data_.hasDefaultWindowing_) + if (GetPresetWindowingsCount() > 0) { - texture->SetCustomWindowing(data_.defaultWindowingCenter_, - data_.defaultWindowingWidth_); + texture->SetCustomWindowing(GetPresetWindowingCenter(0), GetPresetWindowingWidth(0)); } switch (GetImageInformation().GetPhotometricInterpretation())
--- a/OrthancStone/Sources/Toolbox/DicomInstanceParameters.h Mon Nov 23 18:49:42 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/DicomInstanceParameters.h Mon Nov 23 19:24:18 2020 +0100 @@ -55,9 +55,8 @@ bool hasRescale_; double rescaleIntercept_; double rescaleSlope_; - bool hasDefaultWindowing_; - float defaultWindowingCenter_; - float defaultWindowingWidth_; + Vector presetWindowingCenters_; + Vector presetWindowingWidths_; bool hasIndexInSeries_; unsigned int indexInSeries_; std::string doseUnits_; @@ -182,14 +181,11 @@ double GetRescaleSlope() const; - bool HasDefaultWindowing() const - { - return data_.hasDefaultWindowing_; - } + size_t GetPresetWindowingsCount() const; - float GetDefaultWindowingCenter() const; + float GetPresetWindowingCenter(size_t i) const; - float GetDefaultWindowingWidth() const; + float GetPresetWindowingWidth(size_t i) const; Orthanc::PixelFormat GetExpectedPixelFormat() const;