Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp @ 2171:8e3c403cc643
Improved support of the (0028,9132) tag for Philips multiframe images
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 22 Oct 2024 15:40:40 +0200 |
parents | fe5406abd43f |
children | 2410a171ebfb |
comparison
equal
deleted
inserted
replaced
2170:7e8b918b0482 | 2171:8e3c403cc643 |
---|---|
30 | 30 |
31 #include <Images/Image.h> | 31 #include <Images/Image.h> |
32 #include <Images/ImageProcessing.h> | 32 #include <Images/ImageProcessing.h> |
33 #include <Logging.h> | 33 #include <Logging.h> |
34 #include <OrthancException.h> | 34 #include <OrthancException.h> |
35 #include <SerializationToolbox.h> | |
35 #include <Toolbox.h> | 36 #include <Toolbox.h> |
36 | 37 |
37 | 38 |
38 namespace OrthancStone | 39 namespace OrthancStone |
39 { | 40 { |
227 | 228 |
228 if (!dicom.HasTag(Orthanc::DICOM_TAG_INSTANCE_NUMBER) || | 229 if (!dicom.HasTag(Orthanc::DICOM_TAG_INSTANCE_NUMBER) || |
229 !dicom.GetValue(Orthanc::DICOM_TAG_INSTANCE_NUMBER).ParseInteger32(instanceNumber_)) | 230 !dicom.GetValue(Orthanc::DICOM_TAG_INSTANCE_NUMBER).ParseInteger32(instanceNumber_)) |
230 { | 231 { |
231 instanceNumber_ = 0; | 232 instanceNumber_ = 0; |
233 } | |
234 | |
235 | |
236 static const Orthanc::DicomTag DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE(0x5200, 0x9230); | |
237 static const Orthanc::DicomTag DICOM_TAG_FRAME_VOI_LUT_SEQUENCE_ATTRIBUTE(0x0028, 0x9132); | |
238 | |
239 const Orthanc::DicomValue* frames = dicom.TestAndGetValue(DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE); | |
240 if (frames != NULL && | |
241 hasNumberOfFrames_ && | |
242 frames->IsSequence()) | |
243 { | |
244 /** | |
245 * New in Stone Web viewer 2.2: Deal with Philips multiframe | |
246 * (cf. mail from Tomas Kenda on 2021-08-17). This cannot be done | |
247 * in LoadSeriesDetailsFromInstance, as the "Per Frame Functional Groups Sequence" | |
248 * is not available at that point. | |
249 **/ | |
250 | |
251 const Json::Value& sequence = frames->GetSequenceContent(); | |
252 | |
253 perFrameWindowing_.resize(numberOfFrames_); | |
254 | |
255 // This corresponds to "ParsedDicomFile::GetDefaultWindowing()" | |
256 for (Json::ArrayIndex i = 0; i < sequence.size(); i++) | |
257 { | |
258 if (i < numberOfFrames_ && | |
259 sequence[i].isMember(DICOM_TAG_FRAME_VOI_LUT_SEQUENCE_ATTRIBUTE.Format())) | |
260 { | |
261 const Json::Value& v = sequence[i][DICOM_TAG_FRAME_VOI_LUT_SEQUENCE_ATTRIBUTE.Format()]; | |
262 | |
263 static const char* KEY_VALUE = "Value"; | |
264 | |
265 if (v.isMember(KEY_VALUE) && | |
266 v[KEY_VALUE].type() == Json::arrayValue && | |
267 v[KEY_VALUE].size() >= 1 && | |
268 v[KEY_VALUE][0].isMember(Orthanc::DICOM_TAG_WINDOW_CENTER.Format()) && | |
269 v[KEY_VALUE][0].isMember(Orthanc::DICOM_TAG_WINDOW_WIDTH.Format()) && | |
270 v[KEY_VALUE][0][Orthanc::DICOM_TAG_WINDOW_CENTER.Format()].isMember(KEY_VALUE) && | |
271 v[KEY_VALUE][0][Orthanc::DICOM_TAG_WINDOW_WIDTH.Format()].isMember(KEY_VALUE)) | |
272 { | |
273 const Json::Value& scenter = v[KEY_VALUE][0][Orthanc::DICOM_TAG_WINDOW_CENTER.Format()][KEY_VALUE]; | |
274 const Json::Value& swidth = v[KEY_VALUE][0][Orthanc::DICOM_TAG_WINDOW_WIDTH.Format()][KEY_VALUE]; | |
275 | |
276 double center, width; | |
277 if (scenter.isString() && | |
278 swidth.isString() && | |
279 Orthanc::SerializationToolbox::ParseDouble(center, scenter.asString()) && | |
280 Orthanc::SerializationToolbox::ParseDouble(width, swidth.asString())) | |
281 { | |
282 perFrameWindowing_[i] = Windowing(center, width); | |
283 } | |
284 else if (scenter.isNumeric() && | |
285 swidth.isNumeric()) | |
286 { | |
287 perFrameWindowing_[i] = Windowing(scenter.asDouble(), swidth.asDouble()); | |
288 } | |
289 } | |
290 } | |
291 } | |
232 } | 292 } |
233 } | 293 } |
234 | 294 |
235 | 295 |
236 double DicomInstanceParameters::GetSliceThickness() const | 296 double DicomInstanceParameters::GetSliceThickness() const |
822 else | 882 else |
823 { | 883 { |
824 return (data_.frameOffsets_[0] > data_.frameOffsets_[1]); | 884 return (data_.frameOffsets_[0] > data_.frameOffsets_[1]); |
825 } | 885 } |
826 } | 886 } |
887 | |
888 | |
889 bool DicomInstanceParameters::LookupPerFrameWindowing(Windowing& windowing, | |
890 unsigned int frame) const | |
891 { | |
892 if (frame < data_.perFrameWindowing_.size()) | |
893 { | |
894 windowing = data_.perFrameWindowing_[frame]; | |
895 return true; | |
896 } | |
897 else | |
898 { | |
899 return false; | |
900 } | |
901 } | |
827 } | 902 } |