Mercurial > hg > orthanc-wsi
changeset 279:77afef2cf64b
automated extraction of the imaged volume if using OpenSlide
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 12 Jul 2023 18:06:34 +0200 |
parents | 169f168ba07a |
children | 34b507959e32 b5b9719ef1c0 |
files | Applications/Dicomizer.cpp Framework/ImagedVolumeParameters.cpp Framework/ImagedVolumeParameters.h Framework/Inputs/OpenSlidePyramid.cpp Framework/Inputs/OpenSlidePyramid.h NEWS |
diffstat | 6 files changed, 109 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- 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<float>()->default_value(15), - "Width of the specimen (in mm)") - (OPTION_IMAGED_HEIGHT, boost::program_options::value<float>()->default_value(15), - "Height of the specimen (in mm)") + (OPTION_IMAGED_WIDTH, boost::program_options::value<float>(), + "Width of the specimen (in mm), defaults to 15mm if missing") + (OPTION_IMAGED_HEIGHT, boost::program_options::value<float>(), + "Height of the specimen (in mm), defaults to 15mm if missing") (OPTION_IMAGED_DEPTH, boost::program_options::value<float>()->default_value(1), "Depth of the specimen (in mm)") (OPTION_OFFSET_X, boost::program_options::value<float>()->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<OrthancWSI::OpenSlidePyramid> 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<OrthancWSI::ITiledPyramid> 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);
--- 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; + } }
--- 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 {
--- 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 <Compatibility.h> // For std::unique_ptr #include <Images/ImageProcessing.h> #include <OrthancException.h> +#include <SerializationToolbox.h> #include <Logging.h> #include <memory> @@ -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<double>(image_.GetLevelHeight(0)); + height = mppx / 1000.0 * static_cast<double>(image_.GetLevelWidth(0)); + return true; + } + else + { + return false; + } + } }