Esempio n. 1
0
def load_dicom_zip(filename, statusfunc=lambda s, c, n: None):
    """
    Load Dicom images from given zip file `filename'. This uses the status callback `statusfunc' like load_dicom_dir().
    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.add_file(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())