Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Toolbox/CoordinateSystem3D.cpp @ 1630:78509230f0d7
SortedFrames sharing code with CoordinateSystem3D
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 09 Nov 2020 18:01:32 +0100 |
parents | 8563ea5d8ae4 |
children | 52b8b96cb55f |
comparison
equal
deleted
inserted
replaced
1629:7fc8a3ff09ee | 1630:78509230f0d7 |
---|---|
39 // unity." | 39 // unity." |
40 // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.2.html | 40 // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.2.html |
41 if (!LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(axisX_), 1.0) || | 41 if (!LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(axisX_), 1.0) || |
42 !LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(axisY_), 1.0)) | 42 !LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(axisY_), 1.0)) |
43 { | 43 { |
44 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | 44 LOG(WARNING) << "Invalid 3D geometry: Axes are not normal vectors"; |
45 SetupCanonical(); | |
45 } | 46 } |
46 | 47 |
47 // The vectors within "Image Orientation Patient" must be | 48 // The vectors within "Image Orientation Patient" must be |
48 // orthogonal, according to the DICOM specification: "The row and | 49 // orthogonal, according to the DICOM specification: "The row and |
49 // column direction cosine vectors shall be orthogonal, i.e., | 50 // column direction cosine vectors shall be orthogonal, i.e., |
50 // their dot product shall be zero." | 51 // their dot product shall be zero." |
51 // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.2.html | 52 // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.2.html |
52 if (!LinearAlgebra::IsCloseToZero(boost::numeric::ublas::inner_prod(axisX_, axisY_))) | 53 else if (!LinearAlgebra::IsCloseToZero(boost::numeric::ublas::inner_prod(axisX_, axisY_))) |
53 { | 54 { |
54 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | 55 LOG(WARNING) << "Invalid 3D geometry: Image orientation patient is not orthogonal"; |
55 } | 56 SetupCanonical(); |
56 | 57 } |
57 LinearAlgebra::CrossProduct(normal_, axisX_, axisY_); | 58 else |
58 | 59 { |
59 d_ = -(normal_[0] * origin_[0] + normal_[1] * origin_[1] + normal_[2] * origin_[2]); | 60 LinearAlgebra::CrossProduct(normal_, axisX_, axisY_); |
60 | 61 |
61 // Just a sanity check, it should be useless by construction | 62 d_ = -(normal_[0] * origin_[0] + normal_[1] * origin_[1] + normal_[2] * origin_[2]); |
62 assert(LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(normal_), 1.0)); | 63 |
64 // Just a sanity check, it should be useless by construction | |
65 assert(LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(normal_), 1.0)); | |
66 } | |
63 } | 67 } |
64 | 68 |
65 | 69 |
66 void CoordinateSystem3D::SetupCanonical() | 70 void CoordinateSystem3D::SetupCanonical() |
67 { | 71 { |
72 valid_ = false; | |
73 | |
68 LinearAlgebra::AssignVector(origin_, 0, 0, 0); | 74 LinearAlgebra::AssignVector(origin_, 0, 0, 0); |
69 LinearAlgebra::AssignVector(axisX_, 1, 0, 0); | 75 LinearAlgebra::AssignVector(axisX_, 1, 0, 0); |
70 LinearAlgebra::AssignVector(axisY_, 0, 1, 0); | 76 LinearAlgebra::AssignVector(axisY_, 0, 1, 0); |
71 CheckAndComputeNormal(); | 77 LinearAlgebra::AssignVector(normal_, 0, 0, 1); |
78 d_ = 0; | |
72 } | 79 } |
73 | 80 |
74 | 81 |
75 CoordinateSystem3D::CoordinateSystem3D(const Vector& origin, | 82 CoordinateSystem3D::CoordinateSystem3D(const Vector& origin, |
76 const Vector& axisX, | 83 const Vector& axisX, |
77 const Vector& axisY) : | 84 const Vector& axisY) : |
85 valid_(true), | |
78 origin_(origin), | 86 origin_(origin), |
79 axisX_(axisX), | 87 axisX_(axisX), |
80 axisY_(axisY) | 88 axisY_(axisY) |
81 { | 89 { |
82 CheckAndComputeNormal(); | 90 CheckAndComputeNormal(); |
84 | 92 |
85 | 93 |
86 void CoordinateSystem3D::Setup(const std::string& imagePositionPatient, | 94 void CoordinateSystem3D::Setup(const std::string& imagePositionPatient, |
87 const std::string& imageOrientationPatient) | 95 const std::string& imageOrientationPatient) |
88 { | 96 { |
97 valid_ = true; | |
98 | |
89 std::string tmpPosition = Orthanc::Toolbox::StripSpaces(imagePositionPatient); | 99 std::string tmpPosition = Orthanc::Toolbox::StripSpaces(imagePositionPatient); |
90 std::string tmpOrientation = Orthanc::Toolbox::StripSpaces(imageOrientationPatient); | 100 std::string tmpOrientation = Orthanc::Toolbox::StripSpaces(imageOrientationPatient); |
91 | 101 |
92 Vector orientation; | 102 Vector orientation; |
93 if (!LinearAlgebra::ParseVector(origin_, tmpPosition) || | 103 if (!LinearAlgebra::ParseVector(origin_, tmpPosition) || |
94 !LinearAlgebra::ParseVector(orientation, tmpOrientation) || | 104 !LinearAlgebra::ParseVector(orientation, tmpOrientation) || |
95 origin_.size() != 3 || | 105 origin_.size() != 3 || |
96 orientation.size() != 6) | 106 orientation.size() != 6) |
97 { | 107 { |
98 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | 108 LOG(WARNING) << "Bad 3D geometry: image position/orientation patient: \"" |
99 } | 109 << tmpPosition << "\" / \"" << tmpOrientation << "\""; |
100 | 110 SetupCanonical(); |
101 axisX_.resize(3); | 111 } |
102 axisX_[0] = orientation[0]; | 112 else |
103 axisX_[1] = orientation[1]; | 113 { |
104 axisX_[2] = orientation[2]; | 114 axisX_.resize(3); |
105 | 115 axisX_[0] = orientation[0]; |
106 axisY_.resize(3); | 116 axisX_[1] = orientation[1]; |
107 axisY_[0] = orientation[3]; | 117 axisX_[2] = orientation[2]; |
108 axisY_[1] = orientation[4]; | 118 |
109 axisY_[2] = orientation[5]; | 119 axisY_.resize(3); |
110 | 120 axisY_[0] = orientation[3]; |
111 CheckAndComputeNormal(); | 121 axisY_[1] = orientation[4]; |
122 axisY_[2] = orientation[5]; | |
123 | |
124 CheckAndComputeNormal(); | |
125 } | |
112 } | 126 } |
113 | 127 |
114 | 128 |
115 CoordinateSystem3D::CoordinateSystem3D(const IDicomDataset& dicom) | 129 CoordinateSystem3D::CoordinateSystem3D(const IDicomDataset& dicom) |
116 { | 130 { |