comparison OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp @ 4777:3b78ba359db3

Support detection of windowing and rescale in Philips multiframe images
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 30 Aug 2021 11:41:05 +0200
parents 9f207131c7f4
children ba1bebbd75d2
comparison
equal deleted inserted replaced
4776:79d4e155592b 4777:3b78ba359db3
2742 2742
2743 { 2743 {
2744 std::unique_ptr<ParsedDicomFile> dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); 2744 std::unique_ptr<ParsedDicomFile> dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, ""));
2745 2745
2746 DicomMap m; 2746 DicomMap m;
2747 ASSERT_TRUE(dicom->LookupSubSequence(m, DicomPath(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE), 0)); 2747 ASSERT_TRUE(dicom->LookupSequenceItem(m, DicomPath(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE), 0));
2748 ASSERT_EQ(2u, m.GetSize()); 2748 ASSERT_EQ(2u, m.GetSize());
2749 ASSERT_EQ("1.2.840.113619.2.176.2025.1499492.7040.1171286241.719", 2749 ASSERT_EQ("1.2.840.113619.2.176.2025.1499492.7040.1171286241.719",
2750 m.GetStringValue(DICOM_TAG_REFERENCED_SOP_INSTANCE_UID, "", false)); 2750 m.GetStringValue(DICOM_TAG_REFERENCED_SOP_INSTANCE_UID, "", false));
2751 2751
2752 ASSERT_TRUE(dicom->LookupSubSequence(m, DicomPath(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE), 1)); 2752 ASSERT_TRUE(dicom->LookupSequenceItem(m, DicomPath(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE), 1));
2753 ASSERT_EQ(2u, m.GetSize()); 2753 ASSERT_EQ(2u, m.GetSize());
2754 ASSERT_EQ("1.2.840.113619.2.176.2025.1499492.7040.1171286241.726", 2754 ASSERT_EQ("1.2.840.113619.2.176.2025.1499492.7040.1171286241.726",
2755 m.GetStringValue(DICOM_TAG_REFERENCED_SOP_INSTANCE_UID, "", false)); 2755 m.GetStringValue(DICOM_TAG_REFERENCED_SOP_INSTANCE_UID, "", false));
2756 2756
2757 ASSERT_FALSE(dicom->LookupSubSequence(m, DicomPath(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE), 2)); 2757 ASSERT_FALSE(dicom->LookupSequenceItem(m, DicomPath(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE), 2));
2758 2758
2759 ASSERT_TRUE(dicom->LookupSubSequence(m, DicomPath(DicomTag(0x0008, 0x1250), 0, DicomTag(0x0040, 0xa170)), 0)); 2759 ASSERT_TRUE(dicom->LookupSequenceItem(m, DicomPath(DicomTag(0x0008, 0x1250), 0, DicomTag(0x0040, 0xa170)), 0));
2760 ASSERT_EQ(2u, m.GetSize()); 2760 ASSERT_EQ(2u, m.GetSize());
2761 ASSERT_EQ("122403", m.GetStringValue(DicomTag(0x0008, 0x0100), "", false)); 2761 ASSERT_EQ("122403", m.GetStringValue(DicomTag(0x0008, 0x0100), "", false));
2762 ASSERT_EQ("WORLD", m.GetStringValue(DICOM_TAG_SERIES_DESCRIPTION, "", false)); 2762 ASSERT_EQ("WORLD", m.GetStringValue(DICOM_TAG_SERIES_DESCRIPTION, "", false));
2763 2763
2764 ASSERT_FALSE(dicom->LookupSubSequence(m, DicomPath(DicomTag(0x0008, 0x1250), 0, DicomTag(0x0040, 0xa170)), 1)); 2764 ASSERT_FALSE(dicom->LookupSequenceItem(m, DicomPath(DicomTag(0x0008, 0x1250), 0, DicomTag(0x0040, 0xa170)), 1));
2765 } 2765 }
2766 } 2766 }
2767 2767
2768 2768
2769 TEST(FromDcmtkBridge, VisitorRemoveTag) 2769 TEST(FromDcmtkBridge, VisitorRemoveTag)
3017 } 3017 }
3018 } 3018 }
3019 3019
3020 3020
3021 3021
3022 TEST(ParsedDicomFile, ImageInformation)
3023 {
3024 double wc, ww;
3025 double ri, rs;
3026 PhotometricInterpretation p;
3027
3028 {
3029 ParsedDicomFile dicom(false);
3030 dicom.GetDefaultWindowing(wc, ww, 5);
3031 dicom.GetRescale(ri, rs, 5);
3032 ASSERT_DOUBLE_EQ(128.0, wc);
3033 ASSERT_DOUBLE_EQ(256.0, ww);
3034 ASSERT_FALSE(dicom.LookupPhotometricInterpretation(p));
3035 ASSERT_DOUBLE_EQ(0.0, ri);
3036 ASSERT_DOUBLE_EQ(1.0, rs);
3037 }
3038
3039 {
3040 ParsedDicomFile dicom(false);
3041 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_BitsStored, "4").good());
3042 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_PhotometricInterpretation, "RGB").good());
3043 dicom.GetDefaultWindowing(wc, ww, 5);
3044 ASSERT_DOUBLE_EQ(8.0, wc);
3045 ASSERT_DOUBLE_EQ(16.0, ww);
3046 ASSERT_TRUE(dicom.LookupPhotometricInterpretation(p));
3047 ASSERT_EQ(PhotometricInterpretation_RGB, p);
3048 }
3049
3050 {
3051 ParsedDicomFile dicom(false);
3052 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_WindowCenter, "12").good());
3053 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_WindowWidth, "-22").good());
3054 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_RescaleIntercept, "-22").good());
3055 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_RescaleSlope, "-23").good());
3056 dicom.GetDefaultWindowing(wc, ww, 5);
3057 dicom.GetRescale(ri, rs, 5);
3058 ASSERT_DOUBLE_EQ(12.0, wc);
3059 ASSERT_DOUBLE_EQ(-22.0, ww);
3060 ASSERT_DOUBLE_EQ(-22.0, ri);
3061 ASSERT_DOUBLE_EQ(-23.0, rs);
3062 }
3063
3064 {
3065 ParsedDicomFile dicom(false);
3066 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_WindowCenter, "12\\13\\14").good());
3067 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_WindowWidth, "-22\\-23\\-24").good());
3068 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_RescaleIntercept, "32\\33\\34").good());
3069 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString(DCM_RescaleSlope, "-42\\-43\\-44").good());
3070 dicom.GetDefaultWindowing(wc, ww, 5);
3071 dicom.GetRescale(ri, rs, 5);
3072 ASSERT_DOUBLE_EQ(12.0, wc);
3073 ASSERT_DOUBLE_EQ(-22.0, ww);
3074 ASSERT_DOUBLE_EQ(32.0, ri);
3075 ASSERT_DOUBLE_EQ(-42.0, rs);
3076 }
3077
3078 {
3079 // Philips multiframe
3080 Json::Value v = Json::objectValue;
3081 v["PerFrameFunctionalGroupsSequence"][0]["FrameVOILUTSequence"][0]["WindowCenter"] = "614";
3082 v["PerFrameFunctionalGroupsSequence"][0]["FrameVOILUTSequence"][0]["WindowWidth"] = "1067";
3083 v["PerFrameFunctionalGroupsSequence"][0]["PixelValueTransformationSequence"][0]["RescaleIntercept"] = "12";
3084 v["PerFrameFunctionalGroupsSequence"][0]["PixelValueTransformationSequence"][0]["RescaleSlope"] = "2.551648";
3085 v["PerFrameFunctionalGroupsSequence"][1]["FrameVOILUTSequence"][0]["WindowCenter"] = "-61";
3086 v["PerFrameFunctionalGroupsSequence"][1]["FrameVOILUTSequence"][0]["WindowWidth"] = "-63";
3087 v["PerFrameFunctionalGroupsSequence"][1]["PixelValueTransformationSequence"][0]["RescaleIntercept"] = "13";
3088 v["PerFrameFunctionalGroupsSequence"][1]["PixelValueTransformationSequence"][0]["RescaleSlope"] = "-14";
3089 std::unique_ptr<ParsedDicomFile> dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, ""));
3090
3091 dicom->GetDefaultWindowing(wc, ww, 0);
3092 dicom->GetRescale(ri, rs, 0);
3093 ASSERT_DOUBLE_EQ(614.0, wc);
3094 ASSERT_DOUBLE_EQ(1067.0, ww);
3095 ASSERT_DOUBLE_EQ(12.0, ri);
3096 ASSERT_DOUBLE_EQ(2.551648, rs);
3097
3098 dicom->GetDefaultWindowing(wc, ww, 1);
3099 dicom->GetRescale(ri, rs, 1);
3100 ASSERT_DOUBLE_EQ(-61.0, wc);
3101 ASSERT_DOUBLE_EQ(-63.0, ww);
3102 ASSERT_DOUBLE_EQ(13.0, ri);
3103 ASSERT_DOUBLE_EQ(-14.0, rs);
3104
3105 dicom->GetDefaultWindowing(wc, ww, 2);
3106 dicom->GetRescale(ri, rs, 2);
3107 ASSERT_DOUBLE_EQ(128.0, wc);
3108 ASSERT_DOUBLE_EQ(256.0, ww);
3109 ASSERT_DOUBLE_EQ(0.0, ri);
3110 ASSERT_DOUBLE_EQ(1.0, rs);
3111 }
3112
3113 {
3114 // RT-DOSE
3115 Json::Value v = Json::objectValue;
3116 v["RescaleIntercept"] = "10";
3117 v["RescaleSlope"] = "20";
3118 v["PerFrameFunctionalGroupsSequence"][0]["PixelValueTransformationSequence"][0]["RescaleIntercept"] = "30";
3119 v["PerFrameFunctionalGroupsSequence"][0]["PixelValueTransformationSequence"][0]["RescaleSlope"] = "40";
3120 std::unique_ptr<ParsedDicomFile> dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, ""));
3121
3122 dicom->GetRescale(ri, rs, 0);
3123 ASSERT_DOUBLE_EQ(10.0, ri);
3124 ASSERT_DOUBLE_EQ(20.0, rs);
3125
3126 v["SOPClassUID"] = "1.2.840.10008.5.1.4.1.1.481.2";
3127 dicom.reset(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, ""));
3128 dicom->GetRescale(ri, rs, 0);
3129 ASSERT_DOUBLE_EQ(0.0, ri);
3130 ASSERT_DOUBLE_EQ(1.0, rs);
3131 }
3132 }
3133
3134
3135
3136
3022 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 3137 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1
3023 3138
3024 #include "../Sources/DicomNetworking/DicomStoreUserConnection.h" 3139 #include "../Sources/DicomNetworking/DicomStoreUserConnection.h"
3025 #include "../Sources/DicomParsing/DcmtkTranscoder.h" 3140 #include "../Sources/DicomParsing/DcmtkTranscoder.h"
3026 3141