Mercurial > hg > orthanc-stone
changeset 1630:78509230f0d7
SortedFrames sharing code with CoordinateSystem3D
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 09 Nov 2020 18:01:32 +0100 |
parents | 7fc8a3ff09ee |
children | 960bb5fcc440 |
files | Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Sources/Toolbox/CoordinateSystem3D.cpp OrthancStone/Sources/Toolbox/CoordinateSystem3D.h OrthancStone/Sources/Toolbox/SortedFrames.cpp OrthancStone/Sources/Toolbox/SortedFrames.h UnitTestsSources/UnitTestsMain.cpp |
diffstat | 6 files changed, 81 insertions(+), 71 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Mon Nov 09 15:14:37 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Mon Nov 09 18:01:32 2020 +0100 @@ -2250,7 +2250,7 @@ static boost::shared_ptr<OrthancStone::WebAssemblyLoadersContext> context_; static std::string stringBuffer_; static bool softwareRendering_ = false; -static WebViewerAction leftButtonAction_ = WebViewerAction_Rotate; // WebViewerAction_GrayscaleWindowing; +static WebViewerAction leftButtonAction_ = WebViewerAction_Crosshair; //WebViewerAction_GrayscaleWindowing; static WebViewerAction middleButtonAction_ = WebViewerAction_Pan; static WebViewerAction rightButtonAction_ = WebViewerAction_Zoom;
--- a/OrthancStone/Sources/Toolbox/CoordinateSystem3D.cpp Mon Nov 09 15:14:37 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/CoordinateSystem3D.cpp Mon Nov 09 18:01:32 2020 +0100 @@ -41,7 +41,8 @@ if (!LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(axisX_), 1.0) || !LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(axisY_), 1.0)) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + LOG(WARNING) << "Invalid 3D geometry: Axes are not normal vectors"; + SetupCanonical(); } // The vectors within "Image Orientation Patient" must be @@ -49,32 +50,39 @@ // column direction cosine vectors shall be orthogonal, i.e., // their dot product shall be zero." // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.2.html - if (!LinearAlgebra::IsCloseToZero(boost::numeric::ublas::inner_prod(axisX_, axisY_))) + else if (!LinearAlgebra::IsCloseToZero(boost::numeric::ublas::inner_prod(axisX_, axisY_))) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + LOG(WARNING) << "Invalid 3D geometry: Image orientation patient is not orthogonal"; + SetupCanonical(); } + else + { + LinearAlgebra::CrossProduct(normal_, axisX_, axisY_); - LinearAlgebra::CrossProduct(normal_, axisX_, axisY_); + d_ = -(normal_[0] * origin_[0] + normal_[1] * origin_[1] + normal_[2] * origin_[2]); - d_ = -(normal_[0] * origin_[0] + normal_[1] * origin_[1] + normal_[2] * origin_[2]); - - // Just a sanity check, it should be useless by construction - assert(LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(normal_), 1.0)); + // Just a sanity check, it should be useless by construction + assert(LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(normal_), 1.0)); + } } void CoordinateSystem3D::SetupCanonical() { + valid_ = false; + LinearAlgebra::AssignVector(origin_, 0, 0, 0); LinearAlgebra::AssignVector(axisX_, 1, 0, 0); LinearAlgebra::AssignVector(axisY_, 0, 1, 0); - CheckAndComputeNormal(); + LinearAlgebra::AssignVector(normal_, 0, 0, 1); + d_ = 0; } CoordinateSystem3D::CoordinateSystem3D(const Vector& origin, const Vector& axisX, const Vector& axisY) : + valid_(true), origin_(origin), axisX_(axisX), axisY_(axisY) @@ -86,6 +94,8 @@ void CoordinateSystem3D::Setup(const std::string& imagePositionPatient, const std::string& imageOrientationPatient) { + valid_ = true; + std::string tmpPosition = Orthanc::Toolbox::StripSpaces(imagePositionPatient); std::string tmpOrientation = Orthanc::Toolbox::StripSpaces(imageOrientationPatient); @@ -95,20 +105,24 @@ origin_.size() != 3 || orientation.size() != 6) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + LOG(WARNING) << "Bad 3D geometry: image position/orientation patient: \"" + << tmpPosition << "\" / \"" << tmpOrientation << "\""; + SetupCanonical(); } + else + { + axisX_.resize(3); + axisX_[0] = orientation[0]; + axisX_[1] = orientation[1]; + axisX_[2] = orientation[2]; - axisX_.resize(3); - axisX_[0] = orientation[0]; - axisX_[1] = orientation[1]; - axisX_[2] = orientation[2]; + axisY_.resize(3); + axisY_[0] = orientation[3]; + axisY_[1] = orientation[4]; + axisY_[2] = orientation[5]; - axisY_.resize(3); - axisY_[0] = orientation[3]; - axisY_[1] = orientation[4]; - axisY_[2] = orientation[5]; - - CheckAndComputeNormal(); + CheckAndComputeNormal(); + } }
--- a/OrthancStone/Sources/Toolbox/CoordinateSystem3D.h Mon Nov 09 15:14:37 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/CoordinateSystem3D.h Mon Nov 09 18:01:32 2020 +0100 @@ -34,6 +34,7 @@ class CoordinateSystem3D { private: + bool valid_; Vector origin_; Vector normal_; Vector axisX_; @@ -71,6 +72,11 @@ explicit CoordinateSystem3D(const Orthanc::DicomMap& dicom); + bool IsValid() const + { + return valid_; + } + const Vector& GetNormal() const { return normal_;
--- a/OrthancStone/Sources/Toolbox/SortedFrames.cpp Mon Nov 09 15:14:37 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/SortedFrames.cpp Mon Nov 09 18:01:32 2020 +0100 @@ -29,7 +29,8 @@ namespace OrthancStone { - SortedFrames::Instance::Instance(const Orthanc::DicomMap& tags) + SortedFrames::Instance::Instance(const Orthanc::DicomMap& tags) : + geometry_(tags) { tags_.Assign(tags); @@ -58,40 +59,9 @@ { monochrome1_ = false; } - - hasPosition_ = ( - LinearAlgebra::ParseVector(position_, tags, Orthanc::DICOM_TAG_IMAGE_POSITION_PATIENT) && - position_.size() == 3 && - GeometryToolbox::ComputeNormal(normal_, tags)); } - const Vector& SortedFrames::Instance::GetNormal() const - { - if (hasPosition_) - { - return normal_; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); - } - } - - - const Vector& SortedFrames::Instance::GetPosition() const - { - if (hasPosition_) - { - return position_; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); - } - } - - SortedFrames::Frame::Frame(const Instance& instance, unsigned int frameNumber) : instance_(&instance), @@ -343,10 +313,10 @@ assert(instances_[*it] != NULL); const Instance& instance = *instances_[*it]; - if (instance.HasPosition()) + if (instance.GetGeometry().IsValid()) { n += 1; - meanNormal += (instance.GetNormal() - meanNormal) / static_cast<float>(n); + meanNormal += (instance.GetGeometry().GetNormal() - meanNormal) / static_cast<float>(n); } } @@ -358,13 +328,13 @@ { assert(instances_[*it] != NULL); const Instance& instance = *instances_[*it]; - + std::string sopInstanceUid; - if (instance.HasPosition() && + if (instance.GetGeometry().IsValid() && instance.GetTags().LookupStringValue( sopInstanceUid, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false)) { - double p = LinearAlgebra::DotProduct(meanNormal, instance.GetPosition()); + double p = LinearAlgebra::DotProduct(meanNormal, instance.GetGeometry().GetOrigin()); items.push_back(SortableItem<float>(static_cast<float>(p), *it, sopInstanceUid)); } }
--- a/OrthancStone/Sources/Toolbox/SortedFrames.h Mon Nov 09 15:14:37 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/SortedFrames.h Mon Nov 09 18:01:32 2020 +0100 @@ -22,6 +22,7 @@ #pragma once +#include "CoordinateSystem3D.h" #include "LinearAlgebra.h" namespace OrthancStone @@ -32,13 +33,11 @@ class Instance : public boost::noncopyable { private: - bool hasPosition_; - Orthanc::DicomMap tags_; - std::string sopInstanceUid_; - unsigned int numberOfFrames_; - Vector normal_; // Only used in "Sort()" - Vector position_; // Only used in "Sort()" - bool monochrome1_; + Orthanc::DicomMap tags_; + std::string sopInstanceUid_; + unsigned int numberOfFrames_; + CoordinateSystem3D geometry_; + bool monochrome1_; public: explicit Instance(const Orthanc::DicomMap& tags); @@ -58,15 +57,11 @@ return numberOfFrames_; } - bool HasPosition() const + const CoordinateSystem3D& GetGeometry() const { - return hasPosition_; + return geometry_; } - const Vector& GetNormal() const; - - const Vector& GetPosition() const; - bool IsMonochrome1() const { return monochrome1_; @@ -164,6 +159,11 @@ return GetInstance(instanceIndex).GetSopInstanceUid(); } + const CoordinateSystem3D& GetInstanceGeometry(size_t instanceIndex) const + { + return GetInstance(instanceIndex).GetGeometry(); + } + bool LookupSopInstanceUid(size_t& instanceIndex, const std::string& sopInstanceUid) const;
--- a/UnitTestsSources/UnitTestsMain.cpp Mon Nov 09 15:14:37 2020 +0100 +++ b/UnitTestsSources/UnitTestsMain.cpp Mon Nov 09 18:01:32 2020 +0100 @@ -879,6 +879,26 @@ } +TEST(CoordinateSystem3D, Basic) +{ + { + OrthancStone::CoordinateSystem3D c; + ASSERT_FALSE(c.IsValid()); + ASSERT_FLOAT_EQ(c.GetNormal()[0], 0); + ASSERT_FLOAT_EQ(c.GetNormal()[1], 0); + ASSERT_FLOAT_EQ(c.GetNormal()[2], 1); + } + + { + OrthancStone::CoordinateSystem3D c("nope1", "nope2"); + ASSERT_FALSE(c.IsValid()); + ASSERT_FLOAT_EQ(c.GetNormal()[0], 0); + ASSERT_FLOAT_EQ(c.GetNormal()[1], 0); + ASSERT_FLOAT_EQ(c.GetNormal()[2], 1); + } +} + + int main(int argc, char **argv) { Orthanc::Logging::Initialize();