Mercurial > hg > orthanc-stone
comparison Framework/Volumes/DicomVolumeImageMPRSlicer.cpp @ 949:32eaf4929b08 toa2019081301
OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader now implement IGeometryProvider so that the geometry reference can be switched (CT or DOSE, for instance) + VolumeImageGeometry::SetSize renamed to VolumeImageGeometry::SetSizeInVoxels + prevent text layer update if text or properties do not change + a few stream operator<< for debug (Vector, Matrix,...) + fixed memory access aligment issues in ImageBuffer3D::ExtractSagittalSlice + fix for wrong screen Y offset of mpr slices in DicomVolumeImageMPRSlicer.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Tue, 13 Aug 2019 16:01:05 +0200 |
parents | 401808e7ff2e |
children | a7351ad54960 |
comparison
equal
deleted
inserted
replaced
948:141cc19e6b7d | 949:32eaf4929b08 |
---|---|
19 **/ | 19 **/ |
20 | 20 |
21 | 21 |
22 #include "DicomVolumeImageMPRSlicer.h" | 22 #include "DicomVolumeImageMPRSlicer.h" |
23 | 23 |
24 #include "../StoneException.h" | |
25 | |
24 #include <Core/OrthancException.h> | 26 #include <Core/OrthancException.h> |
27 //#include <Core/Images/PngWriter.h> | |
28 #include <Core/Images/JpegWriter.h> | |
25 | 29 |
26 namespace OrthancStone | 30 namespace OrthancStone |
27 { | 31 { |
28 void DicomVolumeImageMPRSlicer::Slice::CheckValid() const | 32 void DicomVolumeImageMPRSlicer::Slice::CheckValid() const |
29 { | 33 { |
74 { | 78 { |
75 const DicomInstanceParameters& parameters = volume_.GetDicomParameters(); | 79 const DicomInstanceParameters& parameters = volume_.GetDicomParameters(); |
76 ImageBuffer3D::SliceReader reader(volume_.GetPixelData(), projection_, sliceIndex_); | 80 ImageBuffer3D::SliceReader reader(volume_.GetPixelData(), projection_, sliceIndex_); |
77 texture.reset(dynamic_cast<TextureBaseSceneLayer*> | 81 texture.reset(dynamic_cast<TextureBaseSceneLayer*> |
78 (configurator->CreateTextureFromDicom(reader.GetAccessor(), parameters))); | 82 (configurator->CreateTextureFromDicom(reader.GetAccessor(), parameters))); |
83 | |
84 // <DEBUG-BLOCK> | |
85 #if 0 | |
86 Orthanc::JpegWriter writer; | |
87 writer.SetQuality(60); | |
88 static int index = 0; | |
89 std::string filePath = "C:\\temp\\sliceReader_P"; | |
90 filePath += boost::lexical_cast<std::string>(projection_); | |
91 filePath += "_I"; | |
92 filePath += boost::lexical_cast<std::string>(index); | |
93 filePath += ".jpg"; | |
94 index++; | |
95 writer.WriteToFile(filePath, reader.GetAccessor()); | |
96 #endif | |
97 // <END-OF-DEBUG-BLOCK> | |
79 } | 98 } |
80 | 99 |
81 const CoordinateSystem3D& system = volume_.GetGeometry().GetProjectionGeometry(projection_); | 100 const CoordinateSystem3D& system = volume_.GetGeometry().GetProjectionGeometry(projection_); |
82 | 101 |
83 double x0, y0, x1, y1; | 102 double x0, y0, x1, y1; |
84 cuttingPlane.ProjectPoint(x0, y0, system.GetOrigin()); | 103 cuttingPlane.ProjectPoint(x0, y0, system.GetOrigin()); |
85 cuttingPlane.ProjectPoint(x1, y1, system.GetOrigin() + system.GetAxisX()); | 104 cuttingPlane.ProjectPoint(x1, y1, system.GetOrigin() + system.GetAxisX()); |
105 | |
106 // <DEBUG-BLOCK> | |
107 #if 0 | |
108 { | |
109 LOG(ERROR) << "+----------------------------------------------------+"; | |
110 LOG(ERROR) << "| DicomVolumeImageMPRSlicer::Slice::CreateSceneLayer |"; | |
111 LOG(ERROR) << "+----------------------------------------------------+"; | |
112 std::string projectionString; | |
113 switch (projection_) | |
114 { | |
115 case VolumeProjection_Coronal: | |
116 projectionString = "CORONAL"; | |
117 break; | |
118 case VolumeProjection_Axial: | |
119 projectionString = "CORONAL"; | |
120 break; | |
121 case VolumeProjection_Sagittal: | |
122 projectionString = "SAGITTAL"; | |
123 break; | |
124 default: | |
125 ORTHANC_ASSERT(false); | |
126 } | |
127 if(volume_.GetGeometry().GetDepth() == 200) | |
128 LOG(ERROR) << "| CT IMAGE 512x512 with projection " << projectionString; | |
129 else | |
130 LOG(ERROR) << "| RTDOSE IMAGE NNNxNNN with projection " << projectionString; | |
131 LOG(ERROR) << "+----------------------------------------------------+"; | |
132 LOG(ERROR) << "| cuttingPlane = " << cuttingPlane; | |
133 LOG(ERROR) << "| point to project = " << system.GetOrigin(); | |
134 LOG(ERROR) << "| result = x0: " << x0 << " y0: " << y0; | |
135 LOG(ERROR) << "+----------------------- END ------------------------+"; | |
136 } | |
137 #endif | |
138 // <END-OF-DEBUG-BLOCK> | |
139 | |
140 #if 1 // BGO 2019-08-13 | |
141 // The sagittal coordinate system has a Y vector going down. The displayed | |
142 // image (scene coords) has a Y vector pointing upwards (towards the patient | |
143 // coord Z index) | |
144 // we need to flip the Y local coordinates to get the scene-coord offset. | |
145 // TODO: this is quite ugly. Isn't there a better way? | |
146 if(projection_ == VolumeProjection_Sagittal) | |
147 texture->SetOrigin(x0, -y0); | |
148 else | |
149 texture->SetOrigin(x0, y0); | |
150 #else | |
86 texture->SetOrigin(x0, y0); | 151 texture->SetOrigin(x0, y0); |
152 #endif | |
87 | 153 |
88 double dx = x1 - x0; | 154 double dx = x1 - x0; |
89 double dy = y1 - y0; | 155 double dy = y1 - y0; |
90 if (!LinearAlgebra::IsCloseToZero(dx) || | 156 if (!LinearAlgebra::IsCloseToZero(dx) || |
91 !LinearAlgebra::IsCloseToZero(dy)) | 157 !LinearAlgebra::IsCloseToZero(dy)) |
93 texture->SetAngle(atan2(dy, dx)); | 159 texture->SetAngle(atan2(dy, dx)); |
94 } | 160 } |
95 | 161 |
96 Vector tmp = volume_.GetGeometry().GetVoxelDimensions(projection_); | 162 Vector tmp = volume_.GetGeometry().GetVoxelDimensions(projection_); |
97 texture->SetPixelSpacing(tmp[0], tmp[1]); | 163 texture->SetPixelSpacing(tmp[0], tmp[1]); |
164 | |
165 // <DEBUG-BLOCK> | |
166 { | |
167 //using std::endl; | |
168 //std::stringstream ss; | |
169 //ss << "DicomVolumeImageMPRSlicer::Slice::CreateSceneLayer | cuttingPlane = " << cuttingPlane << " | projection_ = " << projection_ << endl; | |
170 //ss << "volume_.GetGeometry().GetProjectionGeometry(projection_) = " << system << endl; | |
171 //ss << "cuttingPlane.ProjectPoint(x0, y0, system.GetOrigin()); --> | x0 = " << x0 << " | y0 = " << y0 << "| x1 = " << x1 << " | y1 = " << y1 << endl; | |
172 //ss << "volume_.GetGeometry() = " << volume_.GetGeometry() << endl; | |
173 //ss << "volume_.GetGeometry() = " << volume_.GetGeometry() << endl; | |
174 //LOG(ERROR) << ss.str(); | |
175 } | |
176 // <END-OF-DEBUG-BLOCK> | |
98 | 177 |
99 return texture.release(); | 178 return texture.release(); |
100 } | 179 } |
101 | 180 |
102 | 181 |