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 {