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,