Mercurial > hg > orthanc-stone
comparison Framework/Radiography/RadiographyDicomLayer.cpp @ 1196:a5f2a6b04a31
RadiographyScene: windowing is now only applied to the Dicom layer
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Wed, 27 Nov 2019 17:51:33 +0100 |
parents | 35e798b16b65 |
children | 54cbffabdc45 ab958fd99b07 |
comparison
equal
deleted
inserted
replaced
1191:c6a36ecd641d | 1196:a5f2a6b04a31 |
---|---|
26 | 26 |
27 #include <Core/OrthancException.h> | 27 #include <Core/OrthancException.h> |
28 #include <Core/Images/Image.h> | 28 #include <Core/Images/Image.h> |
29 #include <Core/Images/ImageProcessing.h> | 29 #include <Core/Images/ImageProcessing.h> |
30 #include <Plugins/Samples/Common/DicomDatasetReader.h> | 30 #include <Plugins/Samples/Common/DicomDatasetReader.h> |
31 #include "../Toolbox/ImageGeometry.h" | |
31 | 32 |
32 static OrthancPlugins::DicomTag ConvertTag(const Orthanc::DicomTag& tag) | 33 static OrthancPlugins::DicomTag ConvertTag(const Orthanc::DicomTag& tag) |
33 { | 34 { |
34 return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement()); | 35 return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement()); |
35 } | 36 } |
136 converter_.reset(converter); | 137 converter_.reset(converter); |
137 } | 138 } |
138 | 139 |
139 void RadiographyDicomLayer::Render(Orthanc::ImageAccessor& buffer, | 140 void RadiographyDicomLayer::Render(Orthanc::ImageAccessor& buffer, |
140 const AffineTransform2D& viewTransform, | 141 const AffineTransform2D& viewTransform, |
141 ImageInterpolation interpolation) const | 142 ImageInterpolation interpolation, |
143 float windowCenter, | |
144 float windowWidth, | |
145 bool applyWindowing) const | |
142 { | 146 { |
143 if (converted_.get() != NULL) | 147 if (converted_.get() != NULL) |
144 { | 148 { |
145 if (converted_->GetFormat() != Orthanc::PixelFormat_Float32) | 149 if (converted_->GetFormat() != Orthanc::PixelFormat_Float32) |
146 { | 150 { |
156 | 160 |
157 Orthanc::ImageAccessor cropped; | 161 Orthanc::ImageAccessor cropped; |
158 converted_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); | 162 converted_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); |
159 | 163 |
160 t.Apply(buffer, cropped, interpolation, false); | 164 t.Apply(buffer, cropped, interpolation, false); |
165 unsigned int x1, y1, x2, y2; | |
166 OrthancStone::GetProjectiveTransformExtent(x1, y1, x2, y2, | |
167 t.GetHomogeneousMatrix(), | |
168 cropped.GetWidth(), | |
169 cropped.GetHeight(), | |
170 buffer.GetWidth(), | |
171 buffer.GetHeight()); | |
172 | |
173 if (applyWindowing) | |
174 { | |
175 // apply windowing but stay in the range [0.0, 65535.0] | |
176 float w0 = windowCenter - windowWidth / 2.0f; | |
177 float w1 = windowCenter + windowWidth / 2.0f; | |
178 | |
179 if (windowWidth >= 0.001f) // Avoid division by zero at (*) | |
180 { | |
181 float scaling = 1.0f / (w1 - w0) * 65535.0f; | |
182 for (unsigned int y = y1; y <= y2; y++) | |
183 { | |
184 float* p = reinterpret_cast<float*>(buffer.GetRow(y)) + x1; | |
185 | |
186 for (unsigned int x = x1; x <= x2; x++, p++) | |
187 { | |
188 if (*p >= w1) | |
189 { | |
190 *p = 65535.0; | |
191 } | |
192 else if (*p <= w0) | |
193 { | |
194 *p = 0; | |
195 } | |
196 else | |
197 { | |
198 // https://en.wikipedia.org/wiki/Linear_interpolation | |
199 *p = scaling * (*p - w0); // (*) | |
200 } | |
201 } | |
202 } | |
203 } | |
204 } | |
205 | |
161 } | 206 } |
162 } | 207 } |
163 | 208 |
164 | 209 |
165 bool RadiographyDicomLayer::GetDefaultWindowing(float& center, | 210 bool RadiographyDicomLayer::GetDefaultWindowing(float& center, |