Mercurial > hg > orthanc-stone
changeset 2235:6450fd850adf
added support for more types of DICOM SR
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sat, 26 Apr 2025 14:20:19 +0200 (5 weeks ago) |
parents | d9e4d135229b |
children | f276f465ff5a |
files | Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Sources/StoneEnumerations.cpp OrthancStone/Sources/StoneEnumerations.h OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp |
diffstat | 4 files changed, 134 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Sat Apr 26 11:28:30 2025 +0200 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Sat Apr 26 14:20:19 2025 +0200 @@ -889,7 +889,7 @@ std::string sopInstanceUid, sopClassUid; if (message.GetInstance(i).LookupStringValue(sopInstanceUid, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false) && message.GetInstance(i).LookupStringValue(sopClassUid, Orthanc::DICOM_TAG_SOP_CLASS_UID, false) && - OrthancStone::StringToSopClassUid(sopClassUid) == OrthancStone::SopClassUid_ComprehensiveSR) + OrthancStone::IsStructuredReport(OrthancStone::StringToSopClassUid(sopClassUid))) { std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); lock->Schedule( @@ -2860,7 +2860,7 @@ **/ bool isMonochrome1 = false; - if (instance.GetSopClassUid() != OrthancStone::SopClassUid_ComprehensiveSR) + if (!OrthancStone::IsStructuredReport(instance.GetSopClassUid())) { isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() == Orthanc::PhotometricInterpretation_Monochrome1); @@ -3027,7 +3027,7 @@ { lock->RefreshCanvasSize(); - if (instance.GetSopClassUid() == OrthancStone::SopClassUid_ComprehensiveSR) + if (OrthancStone::IsStructuredReport(instance.GetSopClassUid())) { // Fit to the width of the textual report scene.FitTopContent(lock->GetCompositor().GetCanvasWidth(), lock->GetCompositor().GetCanvasHeight(), 0.1); @@ -3162,7 +3162,7 @@ try { std::unique_ptr<Orthanc::ImageAccessor> frame; - if (instance.GetSopClassUid() == OrthancStone::SopClassUid_ComprehensiveSR) + if (OrthancStone::IsStructuredReport(instance.GetSopClassUid())) { OrthancStone::DicomStructuredReport report(const_cast<Orthanc::ParsedDicomFile&>(accessor->GetDicom())); frame.reset(report.Render(font_, GetHighlightedColorInternal(), GetAnnotationsColorInternal()));
--- a/OrthancStone/Sources/StoneEnumerations.cpp Sat Apr 26 11:28:30 2025 +0200 +++ b/OrthancStone/Sources/StoneEnumerations.cpp Sat Apr 26 14:20:19 2025 +0200 @@ -65,10 +65,78 @@ { return SopClassUid_DicomSeg; } + else if (s == "1.2.840.10008.5.1.4.1.1.88.11") + { + return SopClassUid_BasicTextSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.22") + { + return SopClassUid_EnhancedSR; + } else if (s == "1.2.840.10008.5.1.4.1.1.88.33") { return SopClassUid_ComprehensiveSR; } + else if (s == "1.2.840.10008.5.1.4.1.1.88.34") + { + return SopClassUid_Comprehensive3DSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.35") + { + return SopClassUid_ExtensibleSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.50") + { + return SopClassUid_MammographyCADSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.65") + { + return SopClassUid_ChestCADSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.67") + { + return SopClassUid_XRayRadiationDoseSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.68") + { + return SopClassUid_RadiopharmaceuticalRadiationDoseSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.69") + { + return SopClassUid_ColonCADSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.70") + { + return SopClassUid_ImplantationPlanSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.71") + { + return SopClassUid_AcquisitionContextSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.72") + { + return SopClassUid_SimplifiedAdultEchoSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.73") + { + return SopClassUid_PatientRadiationDoseSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.74") + { + return SopClassUid_PlannedImagingAgentAdministrationSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.75") + { + return SopClassUid_PerformedImagingAgentAdministrationSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.76") + { + return SopClassUid_EnhancedXRayRadiationDoseSR; + } + else if (s == "1.2.840.10008.5.1.4.1.1.88.77") + { + return SopClassUid_WaveformAnnotationSR; + } else { //LOG(INFO) << "Other SOP class UID: " << source; @@ -222,11 +290,40 @@ case SopClassUid_VideoPhotographicImageStorage: return SeriesThumbnailType_Video; - case SopClassUid_ComprehensiveSR: - return SeriesThumbnailType_StructuredReport; + default: + break; + } - default: - return SeriesThumbnailType_Unsupported; + if (IsStructuredReport(sopClassUid)) + { + return SeriesThumbnailType_StructuredReport; + } + else + { + return SeriesThumbnailType_Unsupported; } } + + + bool IsStructuredReport(SopClassUid sopClassUid) + { + return (sopClassUid == SopClassUid_BasicTextSR || + sopClassUid == SopClassUid_EnhancedSR || + sopClassUid == SopClassUid_ComprehensiveSR || + sopClassUid == SopClassUid_Comprehensive3DSR || + sopClassUid == SopClassUid_ExtensibleSR || + sopClassUid == SopClassUid_MammographyCADSR || + sopClassUid == SopClassUid_ChestCADSR || + sopClassUid == SopClassUid_XRayRadiationDoseSR || + sopClassUid == SopClassUid_RadiopharmaceuticalRadiationDoseSR || + sopClassUid == SopClassUid_ColonCADSR || + sopClassUid == SopClassUid_ImplantationPlanSR || + sopClassUid == SopClassUid_AcquisitionContextSR || + sopClassUid == SopClassUid_SimplifiedAdultEchoSR || + sopClassUid == SopClassUid_PatientRadiationDoseSR || + sopClassUid == SopClassUid_PlannedImagingAgentAdministrationSR || + sopClassUid == SopClassUid_PerformedImagingAgentAdministrationSR || + sopClassUid == SopClassUid_EnhancedXRayRadiationDoseSR || + sopClassUid == SopClassUid_WaveformAnnotationSR); + } }
--- a/OrthancStone/Sources/StoneEnumerations.h Sat Apr 26 11:28:30 2025 +0200 +++ b/OrthancStone/Sources/StoneEnumerations.h Sat Apr 26 14:20:19 2025 +0200 @@ -106,6 +106,8 @@ KeyboardKeys_F12 = 123, }; + + // https://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_b.5.html enum SopClassUid { SopClassUid_Other, @@ -117,7 +119,26 @@ SopClassUid_VideoMicroscopicImageStorage, SopClassUid_VideoPhotographicImageStorage, SopClassUid_DicomSeg, - SopClassUid_ComprehensiveSR + + // All the possible DICOM-SR + SopClassUid_BasicTextSR, + SopClassUid_EnhancedSR, + SopClassUid_ComprehensiveSR, + SopClassUid_Comprehensive3DSR, + SopClassUid_ExtensibleSR, + SopClassUid_MammographyCADSR, + SopClassUid_ChestCADSR, + SopClassUid_XRayRadiationDoseSR, + SopClassUid_RadiopharmaceuticalRadiationDoseSR, + SopClassUid_ColonCADSR, + SopClassUid_ImplantationPlanSR, + SopClassUid_AcquisitionContextSR, + SopClassUid_SimplifiedAdultEchoSR, + SopClassUid_PatientRadiationDoseSR, + SopClassUid_PlannedImagingAgentAdministrationSR, + SopClassUid_PerformedImagingAgentAdministrationSR, + SopClassUid_EnhancedXRayRadiationDoseSR, + SopClassUid_WaveformAnnotationSR }; enum SeriesThumbnailType @@ -184,4 +205,6 @@ unsigned int border = 0); SeriesThumbnailType GetSeriesThumbnailType(SopClassUid sopClassUid); + + bool IsStructuredReport(SopClassUid sopClassUid); }
--- a/OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp Sat Apr 26 11:28:30 2025 +0200 +++ b/OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp Sat Apr 26 14:20:19 2025 +0200 @@ -651,8 +651,9 @@ seriesInstanceUid_ = GetStringValue(dataset, DCM_SeriesInstanceUID); sopInstanceUid_ = GetStringValue(dataset, DCM_SOPInstanceUID); - SopClassUid sopClassUid = StringToSopClassUid(GetStringValue(dataset, DCM_SOPClassUID)); - if (sopClassUid != SopClassUid_ComprehensiveSR) + std::string sopClassUidString = GetStringValue(dataset, DCM_SOPClassUID); + SopClassUid sopClassUid = StringToSopClassUid(sopClassUidString); + if (!IsStructuredReport(sopClassUid)) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } @@ -674,7 +675,8 @@ ReadTextualReport(textualReport_, dataset); - if (IsDicomConcept(dataset, "126000") /* Imaging measurement report */ && + if (sopClassUid == SopClassUid_ComprehensiveSR && + IsDicomConcept(dataset, "126000") /* Imaging measurement report */ && IsDicomTemplate(dataset, "1500") && dataset.tagExists(DCM_CurrentRequestedProcedureEvidenceSequence)) {