def loadDicomZip(filename, statusfunc=lambda s, c, n: None): """ Load Dicom images from given zip file `filename'. This uses the status callback `statusfunc' like loadDicomDir(). Loaded files will have their pixel data thus avoiding the need to reload the zip file when an image is viewed but is at the expense of load time and memory. Return value is a sequence of DicomSeries objects in no particular order. """ series = {} count = 0 with zipfile.ZipFile(filename) as z: names = z.namelist() numfiles = len(names) for n in names: nfilename = "%s?%s" % (filename, n) s = BytesIO(z.read(n)) try: dcm = dicomio.read_file(s) except: pass # ignore files which aren't Dicom files, various exceptions raised so no concise way to do this else: seriesid = dcm.get("SeriesInstanceUID", "???") if seriesid not in series: series[seriesid] = DicomSeries(seriesid, nfilename) # need to load image data now since we don't want to reload the zip file later when an image is viewed try: # attempt to create the image matrix, store None if this doesn't work rslope = float(dcm.get("RescaleSlope", 1) or 1) rinter = float(dcm.get("RescaleIntercept", 0) or 0) img = dcm.pixel_array * rslope + rinter except: img = None s = series[seriesid] s.addFile(nfilename, dcm) s.tagcache[len(s.filenames) - 1] = dcm s.imgcache[len(s.filenames) - 1] = img count += 1 # update status only 100 times, doing it too frequently really slows things down if numfiles < 100 or count % (numfiles // 100) == 0: statusfunc("Loading DICOM files", count, numfiles) statusfunc("", 0, 0) return list(series.values())