# HG changeset patch # User Sebastien Jodogne # Date 1689177994 -7200 # Node ID 77afef2cf64b1bced5eb2cd066e64719395ec586 # Parent 169f168ba07a6372c11e84ce609a01fc00c00d5c automated extraction of the imaged volume if using OpenSlide diff -r 169f168ba07a -r 77afef2cf64b Applications/Dicomizer.cpp --- a/Applications/Dicomizer.cpp Wed Jul 12 17:12:10 2023 +0200 +++ b/Applications/Dicomizer.cpp Wed Jul 12 18:06:34 2023 +0200 @@ -643,10 +643,10 @@ boost::program_options::options_description volumeOptions("Description of the imaged volume"); volumeOptions.add_options() - (OPTION_IMAGED_WIDTH, boost::program_options::value()->default_value(15), - "Width of the specimen (in mm)") - (OPTION_IMAGED_HEIGHT, boost::program_options::value()->default_value(15), - "Height of the specimen (in mm)") + (OPTION_IMAGED_WIDTH, boost::program_options::value(), + "Width of the specimen (in mm), defaults to 15mm if missing") + (OPTION_IMAGED_HEIGHT, boost::program_options::value(), + "Height of the specimen (in mm), defaults to 15mm if missing") (OPTION_IMAGED_DEPTH, boost::program_options::value()->default_value(1), "Depth of the specimen (in mm)") (OPTION_OFFSET_X, boost::program_options::value()->default_value(20), @@ -1010,6 +1010,7 @@ OrthancWSI::ITiledPyramid* OpenInputPyramid(OrthancWSI::ImageCompression& sourceCompression, + OrthancWSI::ImagedVolumeParameters& volume, const std::string& path, const OrthancWSI::DicomizerParameters& parameters) { @@ -1072,9 +1073,26 @@ { LOG(WARNING) << "Trying to open the input pyramid with OpenSlide"; sourceCompression = OrthancWSI::ImageCompression_Unknown; - return new OrthancWSI::OpenSlidePyramid(path, - parameters.GetTargetTileWidth(512), - parameters.GetTargetTileHeight(512)); + + std::unique_ptr openslide( + new OrthancWSI::OpenSlidePyramid(path, parameters.GetTargetTileWidth(512), + parameters.GetTargetTileHeight(512))); + + float volumeWidth, volumeHeight; + if (openslide->LookupImagedVolumeSize(volumeWidth, volumeHeight)) + { + if (!volume.HasWidth()) + { + volume.SetWidth(volumeWidth); + } + + if (!volume.HasHeight()) + { + volume.SetHeight(volumeHeight); + } + } + + return openslide.release(); } catch (Orthanc::OrthancException&) { @@ -1101,7 +1119,7 @@ OrthancWSI::ImageCompression sourceCompression; std::unique_ptr source; - source.reset(OpenInputPyramid(sourceCompression, parameters.GetInputFile(), parameters)); + source.reset(OpenInputPyramid(sourceCompression, volume, parameters.GetInputFile(), parameters)); if (source.get() == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); diff -r 169f168ba07a -r 77afef2cf64b Framework/ImagedVolumeParameters.cpp --- a/Framework/ImagedVolumeParameters.cpp Wed Jul 12 17:12:10 2023 +0200 +++ b/Framework/ImagedVolumeParameters.cpp Wed Jul 12 18:06:34 2023 +0200 @@ -27,25 +27,54 @@ namespace OrthancWSI { - ImagedVolumeParameters::ImagedVolumeParameters() + ImagedVolumeParameters::ImagedVolumeParameters() : + hasWidth_(false), + hasHeight_(false) { - // Typical parameters of a specimen millimeters - width_ = 15; - height_ = 15; + // Typical parameters for a specimen, in millimeters depth_ = 1; offsetX_ = 20; offsetY_ = 40; } + float ImagedVolumeParameters::GetWidth() const + { + if (hasWidth_) + { + return width_; + } + else + { + return 15; // Typical width of a specimen + } + } + + + float ImagedVolumeParameters::GetHeight() const + { + if (hasHeight_) + { + return height_; + } + else + { + return 15; // Typical height of a specimen + } + } + + void ImagedVolumeParameters::SetWidth(float width) { if (width <= 0) { throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - - width_ = width; + else + { + width_ = width; + hasWidth_ = true; + } } @@ -55,8 +84,11 @@ { throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - - height_ = height; + else + { + height_ = height; + hasHeight_ = true; + } } diff -r 169f168ba07a -r 77afef2cf64b Framework/ImagedVolumeParameters.h --- a/Framework/ImagedVolumeParameters.h Wed Jul 12 17:12:10 2023 +0200 +++ b/Framework/ImagedVolumeParameters.h Wed Jul 12 18:06:34 2023 +0200 @@ -27,6 +27,8 @@ class ImagedVolumeParameters { private: + bool hasWidth_; + bool hasHeight_; float width_; float height_; float depth_; @@ -36,15 +38,19 @@ public: ImagedVolumeParameters(); - float GetWidth() const + bool HasWidth() const { - return width_; + return hasWidth_; + } + + bool HasHeight() const + { + return hasHeight_; } - float GetHeight() const - { - return height_; - } + float GetWidth() const; + + float GetHeight() const; float GetDepth() const { diff -r 169f168ba07a -r 77afef2cf64b Framework/Inputs/OpenSlidePyramid.cpp --- a/Framework/Inputs/OpenSlidePyramid.cpp Wed Jul 12 17:12:10 2023 +0200 +++ b/Framework/Inputs/OpenSlidePyramid.cpp Wed Jul 12 18:06:34 2023 +0200 @@ -26,6 +26,7 @@ #include // For std::unique_ptr #include #include +#include #include #include @@ -50,4 +51,28 @@ tileHeight_(tileHeight) { } + + + bool OpenSlidePyramid::LookupImagedVolumeSize(float& width, + float& height) const + { + std::string s; + double mppx; + double mppy; + + if (image_.LookupProperty(s, "openslide.mpp-x") && + Orthanc::SerializationToolbox::ParseDouble(mppx, s) && + image_.LookupProperty(s, "openslide.mpp-y") && + Orthanc::SerializationToolbox::ParseDouble(mppy, s)) + { + // In the 2 lines below, remember to switch X/Y when going from physical to pixel coordinates! + width = mppy / 1000.0 * static_cast(image_.GetLevelHeight(0)); + height = mppx / 1000.0 * static_cast(image_.GetLevelWidth(0)); + return true; + } + else + { + return false; + } + } } diff -r 169f168ba07a -r 77afef2cf64b Framework/Inputs/OpenSlidePyramid.h --- a/Framework/Inputs/OpenSlidePyramid.h Wed Jul 12 17:12:10 2023 +0200 +++ b/Framework/Inputs/OpenSlidePyramid.h Wed Jul 12 18:06:34 2023 +0200 @@ -79,5 +79,8 @@ { return Orthanc::PhotometricInterpretation_RGB; } + + bool LookupImagedVolumeSize(float& width, + float& height) const; }; } diff -r 169f168ba07a -r 77afef2cf64b NEWS --- a/NEWS Wed Jul 12 17:12:10 2023 +0200 +++ b/NEWS Wed Jul 12 18:06:34 2023 +0200 @@ -1,6 +1,9 @@ Pending changes in the mainline =============================== +* Automated extraction of the imaged volume if using OpenSlide + + Version 1.1 (2021-12-11) ========================