changeset 433:cb579ad96a6c

test_multiframe_windowing
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 25 Aug 2021 18:56:20 +0200
parents f4609c97e995
children 2c142e070f19
files Database/MultiframeWindowing.dcm Database/MultiframeWindowing.dump Tests/Tests.py
diffstat 3 files changed, 105 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
Binary file Database/MultiframeWindowing.dcm has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Database/MultiframeWindowing.dump	Wed Aug 25 18:56:20 2021 +0200
@@ -0,0 +1,54 @@
+# dump2dcm --write-xfer-little MultiframeWindowing.dump MultiframeWindowing.dcm
+
+(0008,0016) UI =MRImageStorage                          #  26, 1 SOPClassUID
+(0008,0018) UI [1.2.840.113619.2.176.2025.1499492.7040.1175286242.109] #  54, 1 SOPInstanceUID
+(0020,000d) UI [1.2.840.113619.2.176.2025.1499492.7391.1175285944.390] #  54, 1 StudyInstanceUID
+(0020,000e) UI [1.2.840.113619.2.176.2025.1499492.7391.1175285944.394] #  54, 1 SeriesInstanceUID
+(0028,0004) CS [MONOCHROME2]                            #  12, 1 PhotometricInterpretation
+(0028,0008) IS [4]                                      # Number of frames
+(0028,0010) US 2                                        #   2, 1 Rows
+(0028,0011) US 2                                        #   2, 1 Columns
+(0028,0100) US 16                                       #   2, 1 BitsAllocated
+(0028,0101) US 16                                       #   2, 1 BitsStored
+(0028,0102) US 15                                       #   2, 1 HighBit
+(5200,9230) SQ                              # PerFrameFunctionalGroupsSequence
+  (fffe,e000) na
+    (0028,9145) SQ                          # Frame 1, PixelValueTransformationSequence
+      (fffe,e000) na
+        (0028,1052) DS [0]                  # Rescale intercept
+        (0028,1053) DS [1]                  # Rescale slope
+      (fffe,e00d) na
+    (fffe,e0dd) na
+    (0028,9132) SQ                          # Frame 1, FrameVOILUTSequence
+      (fffe,e000) na
+        (0028,1050) DS [16]                 # Window center
+        (0028,1051) DS [128]                # Window width
+      (fffe,e00d) na
+    (fffe,e0dd) na
+  (fffe,e00d) na
+  (fffe,e000) na
+    (0028,9145) SQ                          # Frame 2, PixelValueTransformationSequence
+      (fffe,e000) na
+        (0028,1052) DS [100]                # Rescale intercept
+        (0028,1053) DS [1]                  # Rescale slope
+      (fffe,e00d) na
+    (fffe,e0dd) na
+  (fffe,e00d) na
+  (fffe,e000) na
+    (0028,9145) SQ                          # Frame 3, PixelValueTransformationSequence
+      (fffe,e000) na
+        (0028,1052) DS [0]                  # Rescale intercept
+        (0028,1053) DS [2]                  # Rescale slope
+      (fffe,e00d) na
+    (fffe,e0dd) na
+  (fffe,e00d) na
+  (fffe,e000) na
+    (0028,9145) SQ                          # Frame 4, PixelValueTransformationSequence
+      (fffe,e000) na
+        (0028,1052) DS [100]                # Rescale intercept
+        (0028,1053) DS [2]                  # Rescale slope
+      (fffe,e00d) na
+    (fffe,e0dd) na
+  (fffe,e00d) na
+(fffe,e0dd) na 
+(7fe0,0010) OW 0\10\20\30\0\10\20\30\0\10\20\30\0\10\20\30  # Pixel data
--- a/Tests/Tests.py	Mon Aug 16 10:46:56 2021 +0200
+++ b/Tests/Tests.py	Wed Aug 25 18:56:20 2021 +0200
@@ -8144,3 +8144,54 @@
         self.assertEqual(1, len(DoGet(_REMOTE, '/instances')))
         DoDelete(_REMOTE, '/studies/%s' % a)
         self.assertEqual(0, len(DoGet(_REMOTE, '/instances')))
+
+
+    def test_multiframe_windowing(self):
+        # Fixed in Orthanc 1.9.7
+        a = UploadInstance(_REMOTE, 'MultiframeWindowing.dcm') ['ID']
+
+        im = GetImage(_REMOTE, '/instances/%s/frames/0/rendered?window-center=127&window-width=256' % a)
+        self.assertEqual(0x00, im.getpixel((0, 0)))
+        self.assertEqual(0x10, im.getpixel((1, 0)))
+        self.assertEqual(0x20, im.getpixel((0, 1)))
+        self.assertEqual(0x30, im.getpixel((1, 1)))
+
+        # Center the window on value "16 == 0x10", thus it has the
+        # mid-level value (i.e. 127)
+        im = GetImage(_REMOTE, '/instances/%s/frames/0/rendered?window-center=16&window-width=128' % a)
+        self.assertEqual(127 - 2 * 16, im.getpixel((0, 0)))
+        self.assertEqual(127, im.getpixel((1, 0)))
+        self.assertEqual(127 + 2 * 16, im.getpixel((0, 1)))
+        self.assertEqual(127 + 2 * 32, im.getpixel((1, 1)))
+
+        # Window center and window width are burned in FrameVOILUTSequence for frame 0
+        im = GetImage(_REMOTE, '/instances/%s/frames/0/rendered' % a)
+        self.assertEqual(127 - 2 * 16, im.getpixel((0, 0)))
+        self.assertEqual(127, im.getpixel((1, 0)))
+        self.assertEqual(127 + 2 * 16, im.getpixel((0, 1)))
+        self.assertEqual(127 + 2 * 32, im.getpixel((1, 1)))
+
+        im = GetImage(_REMOTE, '/instances/%s/frames/1/rendered?window-center=127&window-width=256' % a)
+        self.assertEqual(100, im.getpixel((0, 0)))
+        self.assertEqual(116, im.getpixel((1, 0)))
+        self.assertEqual(132, im.getpixel((0, 1)))
+        self.assertEqual(148, im.getpixel((1, 1)))
+
+        im = GetImage(_REMOTE, '/instances/%s/frames/2/rendered?window-center=127&window-width=256' % a)
+        self.assertEqual(0, im.getpixel((0, 0)))
+        self.assertEqual(32, im.getpixel((1, 0)))
+        self.assertEqual(64, im.getpixel((0, 1)))
+        self.assertEqual(96, im.getpixel((1, 1)))
+
+        im = GetImage(_REMOTE, '/instances/%s/frames/3/rendered?window-center=127&window-width=256' % a)
+        self.assertEqual(100, im.getpixel((0, 0)))
+        self.assertEqual(132, im.getpixel((1, 0)))
+        self.assertEqual(164, im.getpixel((0, 1)))
+        self.assertEqual(196, im.getpixel((1, 1)))
+
+        im = GetImage(_REMOTE, '/instances/%s/frames/0/rendered?window-center=16&window-width=128' % a)
+        self.assertEqual(127 - 2 * 16, im.getpixel((0, 0)))
+        self.assertEqual(127, im.getpixel((1, 0)))
+        self.assertEqual(127 + 2 * 16, im.getpixel((0, 1)))
+        self.assertEqual(127 + 2 * 32, im.getpixel((1, 1)))
+