changeset 304:b8399213b840

fix
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 19 May 2020 18:25:38 +0200
parents cb56f56c98fb
children ed20ead1a8b6
files Database/TransferSyntaxes/1.2.840.10008.1.2.4.50.png Plugins/DicomWeb/Run.py Tests/Tests.py Tests/Toolbox.py
diffstat 4 files changed, 64 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
Binary file Database/TransferSyntaxes/1.2.840.10008.1.2.4.50.png has changed
--- a/Plugins/DicomWeb/Run.py	Tue May 19 17:33:08 2020 +0200
+++ b/Plugins/DicomWeb/Run.py	Tue May 19 18:25:38 2020 +0200
@@ -39,6 +39,8 @@
 import argparse
 import unittest
 import re
+from PIL import ImageChops
+
 from DicomWeb import *
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'Tests'))
@@ -1001,12 +1003,14 @@
         p = DoGetMultipart(ORTHANC, 'dicom-web/studies/1.2.276.0.26.1.1.1.2.2020.45.52293.1506048/series/1.2.276.0.26.1.1.1.2.2020.45.52293.6384450/instances/1.2.276.0.26.1.1.1.2.2020.45.52366.2551599.179568640/frames/5')
         self.assertEqual(1, len(p))
         self.assertEqual(743 * 975 * 3, len(p[0]))
-        self.assertTrue(ComputeMD5(p[0]) in [
-            # The actual value depends on the JPEG decompression algorithm
-            #  $ convert -depth 8 -size 975x743 rgb:tutu.raw pic.png
-            'b952d67da9ff004b0adae3982e89d620',  # With GDCM
-            'b3662c4bfa24a0c73abb08548c63319b',  # With DCMTK
-        ])
+
+        if HasGdcmPlugin(ORTHANC):
+            self.assertTrue(ComputeMD5(p[0]) in [
+                'b952d67da9ff004b0adae3982e89d620', # GDCM >= 3.0
+                'b3662c4bfa24a0c73abb08548c63319b'  # Fallback to DCMTK
+                ])
+        else:
+            self.assertEqual('b3662c4bfa24a0c73abb08548c63319b', ComputeMD5(p[0]))  # DCMTK
 
 
     def test_bitbucket_issue_168(self):
@@ -1157,7 +1161,8 @@
             }
 
         uri = '/dicom-web%s' % UploadAndGetWadoPath('TransferSyntaxes/1.2.840.10008.1.2.4.50.dcm')
-
+        truth = Image.open(GetDatabasePath('TransferSyntaxes/1.2.840.10008.1.2.4.50.png'))
+        
         a = DoGetMultipart(ORTHANC, '%s/frames/1' % uri,
                            headers = { 'Accept' : ACCEPT['1.2.840.10008.1.2.4.50'] },
                            returnHeaders = True)
@@ -1173,9 +1178,13 @@
         a = DoGetMultipart(ORTHANC, '%s/frames/1' % uri)
         self.assertEqual(1, len(a))
         self.assertEqual(480 * 640 * 3, len(a[0]))
-        
+
+        # http://effbot.org/zone/pil-comparing-images.htm
+        img = Image.frombytes('RGB', [ 640, 480 ], a[0])
+        self.assertLessEqual(GetMaxImageDifference(img, truth), 2)
+
         ACCEPT2 = copy.deepcopy(ACCEPT)
-        if ComputeMD5(a[0]) == '654fd026c19daf92bf05137233b4f426':
+        if HasGdcmPlugin(ORTHANC):
             IS_GDCM = True
             ACCEPT2['1.2.840.10008.1.2.1'] = 'multipart/related; type=application/octet-stream'
             del ACCEPT2['1.2.840.10008.1.2']
@@ -1188,9 +1197,10 @@
         self.assertEqual(1, len(a))
         self.assertEqual(480 * 640 * 3, len(a[0]))
 
-        if IS_GDCM:
-            self.assertEqual('654fd026c19daf92bf05137233b4f426', ComputeMD5(a[0]))
-        else:
+        img = Image.frombytes('RGB', [ 640, 480 ], a[0])
+        self.assertLessEqual(GetMaxImageDifference(img, truth), 2)
+
+        if not IS_GDCM:
             self.assertEqual('dfdc79f5070926bbb8ac079ee91f5b91', ComputeMD5(a[0]))
 
 
@@ -1207,8 +1217,9 @@
         if IS_GDCM:
             # This file was failing with GDCM, as it has 2 fragments,
             # and only the first one was returned => the MD5 below is BAD
-            RESULTS['1.2.840.10008.1.2.4.51'] = '901963a322a817946b074f9ed0afa060'
-        
+            #RESULTS['1.2.840.10008.1.2.4.51'] = '901963a322a817946b074f9ed0afa060'
+            pass
+            
         for syntax in ACCEPT2:
             uri = '/dicom-web%s' % UploadAndGetWadoPath('TransferSyntaxes/%s.dcm' % syntax)
             a = DoGetMultipart(ORTHANC, '%s/frames/1' % uri,
--- a/Tests/Tests.py	Tue May 19 17:33:08 2020 +0200
+++ b/Tests/Tests.py	Tue May 19 18:25:38 2020 +0200
@@ -138,11 +138,6 @@
         ]
 
 
-def HasGdcmPlugin():
-    plugins = DoGet(_REMOTE, '/plugins')
-    return ('gdcm' in plugins)
-
-
 class Orthanc(unittest.TestCase):
     def setUp(self):
         if (sys.version_info >= (3, 0)):
@@ -1632,7 +1627,7 @@
         # gdcmconv -i /home/jodogne/DICOM/GdcmDatabase/US_DataSet/HDI5000_US/3EAF5E01 -w -o Issue19.dcm
 
         a = UploadInstance(_REMOTE, 'Issue19.dcm')['ID']
-        if not HasGdcmPlugin():
+        if not HasGdcmPlugin(_REMOTE):
             self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/941ad3c8-05d05b88-560459f9-0eae0e20-6cddd533/preview'))
 
 
@@ -3078,7 +3073,7 @@
         Check('1.2.840.10008.1.2', 'd54aed9f67a100984b42942cc2e9939b')
 
         # JPEG2k image, not supported without GDCM plugin
-        if not HasGdcmPlugin():
+        if not HasGdcmPlugin(_REMOTE):
             Check('1.2.840.10008.1.2.4.90', None)
             Check('1.2.840.10008.1.2.4.91', None)
 
@@ -5535,7 +5530,7 @@
             '1.2.840.10008.1.2.4.70',
         ]
 
-        if HasGdcmPlugin():
+        if HasGdcmPlugin(_REMOTE):
             SYNTAXES = SYNTAXES + [
                 '1.2.840.10008.1.2.4.80',  # This makes DCMTK 3.6.2 crash
                 '1.2.840.10008.1.2.4.81',  # This makes DCMTK 3.6.2 crash
--- a/Tests/Toolbox.py	Tue May 19 17:33:08 2020 +0200
+++ b/Tests/Toolbox.py	Tue May 19 18:25:38 2020 +0200
@@ -32,7 +32,10 @@
 import time
 import zipfile
 
-from PIL import Image
+from PIL import Image, ImageChops
+import math
+import operator
+
 
 if (sys.version_info >= (3, 0)):
     from urllib.parse import urlencode
@@ -389,3 +392,35 @@
         data = subprocess.check_output([ FindExecutable('dcm2xml'), f.name ])
 
     return re.search('<data-set xfer="(.*?)"', data).group(1)
+
+
+def HasGdcmPlugin(orthanc):
+    plugins = DoGet(orthanc, '/plugins')
+    return ('gdcm' in plugins)
+
+
+def _GetMaxImageDifference(im1, im2):
+    h = ImageChops.difference(im1, im2).histogram()
+
+    if len(h) < 256:
+        raise Exception()
+
+    i = len(h) - 1
+    while h[i] == 0:
+        i -= 1
+
+    return i
+    
+
+def GetMaxImageDifference(im1, im2):
+    if im1.mode != im2.mode:
+        raise Exception('Incompatible image modes')
+
+    if im1.mode == 'RGB':
+        red1, green1, blue1 = im1.split()
+        red2, green2, blue2 = im2.split()
+        return max([ _GetMaxImageDifference(red1, red2), 
+                     _GetMaxImageDifference(green1, green2),
+                     _GetMaxImageDifference(blue1, blue2) ])
+    else:
+        return _GetMaxImageDifference(im1, im2)