示例#1
0
def create_image_reader(ds: "Dataset") -> "gdcm.ImageReader":
    """Return a ``gdcm.ImageReader``.

    Parameters
    ----------
    ds : pydicom.dataset.Dataset
        The dataset to create the reader from.

    Returns
    -------
    gdcm.ImageReader
    """
    image_reader = gdcm.ImageReader()
    fname = getattr(ds, 'filename', None)
    if fname and isinstance(fname, str):
        pass
    else:
        # Copy the relevant elements and write to a temporary file to avoid
        #   having to deal with all the possible objects the dataset may
        #   originate with
        new = ds.group_dataset(0x0028)
        new["PixelData"] = ds["PixelData"]  # avoid ambiguous VR
        new.file_meta = ds.file_meta  # type: ignore[has-type]
        tfile = NamedTemporaryFile('wb')
        new.save_as(tfile.name)
        fname = tfile.name

    image_reader.SetFileName(fname)
    return image_reader
示例#2
0
def decomp(file1, file2='temp_file_22.dcm', return_dcm=False):
    #file1 = '/data/gabriel/TAVR/TAVR_Sample_Study/IM-0003-1528.dcm'#sys.argv[1] # input filename

    #file2 = file2#sys.argv[2] # output filename
    if os.path.isfile(file2):
        os.remove(file2)
    reader = gdcm.ImageReader()
    reader.SetFileName(file1)
    reader.GetFile()
    if not reader.Read():
        sys.exit(1)

    change = gdcm.ImageChangeTransferSyntax()
    change.SetTransferSyntax(
        gdcm.TransferSyntax(gdcm.TransferSyntax.ImplicitVRLittleEndian))
    change.SetInput(reader.GetImage())
    if not change.Change():
        sys.exit(1)

    writer = gdcm.ImageWriter()
    writer.SetFileName(file2)
    writer.SetFile(reader.GetFile())
    writer.SetImage(change.GetOutput())
    if not writer.Write():
        sys.exit(1)

    if return_dcm:
        return pydicom.dcmread(file2, force=True)
    else:
        return pydicom.dcmread(file2, force=True).pixel_array
示例#3
0
def decompress(inFile, outFile):
    print("Extract (or copy) %s to %s" % (inFile, outFile))
    try:
        reader = gdcm.ImageReader()
        reader.SetFileName(inFile)
        if not reader.Read():
            raise Exception("Unable to read %s with gdcm.ImageReader()" %
                            inFile)

        change = gdcm.ImageChangeTransferSyntax()
        change.SetTransferSyntax(
            gdcm.TransferSyntax(gdcm.TransferSyntax.ImplicitVRLittleEndian))
        change.SetInput(reader.GetImage())
        if not change.Change():
            raise Exception(
                "Unable to change %s with gdcm.ImageChangeTransferSyntax()" %
                inFile)

        writer = gdcm.ImageWriter()
        writer.SetFileName(outFile)
        writer.SetFile(reader.GetFile())
        writer.SetImage(change.GetOutput())
        if not writer.Write():
            raise Exception("Unable to write %s with gdcm.ImageWriter()" %
                            outFile)

    except Exception as e:
        sys.stderr.write("%s, copying instead" % str(e))
        if inFile is not outFile:
            shutil.copyfile(inFile, outFile)
示例#4
0
def dcmmf2memmap(dcm_file, orientation):
    reader = gdcm.ImageReader()
    reader.SetFileName(dcm_file)
    reader.Read()
    image = reader.GetImage()
    xs, ys, zs = image.GetSpacing()
    pf = image.GetPixelFormat()
    np_image = converters.gdcm_to_numpy(image, pf.GetSamplesPerPixel() == 1)
    temp_file = tempfile.mktemp()
    matrix = numpy.memmap(temp_file, mode='w+', dtype='int16', shape=np_image.shape)
    print("Number of dimensions", np_image.shape)
    z, y, x = np_image.shape
    if orientation == 'CORONAL':
        spacing = xs, zs, ys
        matrix.shape = y, z, x
        for n in range(z):
            matrix[:, n, :] = np_image[n][::-1]
    elif orientation == 'SAGITTAL':
        spacing = zs, ys, xs
        matrix.shape = y, x, z
        for n in range(z):
            matrix[:, :, n] = np_image[n][::-1]
    else:
        spacing = xs, ys, zs
        matrix[:] = np_image[:, ::-1, :]

    matrix.flush()
    scalar_range = matrix.min(), matrix.max()

    return matrix, scalar_range, spacing, temp_file
示例#5
0
def dcmmf2memmap(dcm_file, orientation):
    reader = gdcm.ImageReader()
    reader.SetFileName(dcm_file)
    reader.Read()
    image = reader.GetImage()
    xs, ys, zs = image.GetSpacing()
    pf = image.GetPixelFormat()
    samples_per_pixel = pf.GetSamplesPerPixel()
    np_image = converters.gdcm_to_numpy(image, pf.GetSamplesPerPixel() == 1)
    if samples_per_pixel == 3:
        np_image = image_normalize(rgb2gray(np_image), 0, 255)
    temp_file = tempfile.mktemp()
    matrix = numpy.memmap(temp_file, mode="w+", dtype="int16", shape=np_image.shape)
    z, y, x = np_image.shape
    if orientation == "CORONAL":
        spacing = xs, zs, ys
        matrix.shape = y, z, x
        for n in range(z):
            matrix[:, n, :] = np_image[n][::-1]
    elif orientation == "SAGITTAL":
        spacing = zs, ys, xs
        matrix.shape = y, x, z
        for n in range(z):
            matrix[:, :, n] = np_image[n][::-1]
    else:
        spacing = xs, ys, zs
        matrix[:] = np_image[:, ::-1, :]

    matrix.flush()
    scalar_range = matrix.min(), matrix.max()

    return matrix, scalar_range, spacing, temp_file
示例#6
0
 def numpy(self):
     """ Grabs image data and converts it to a numpy array """
     # load GDCM's image reading functionality
     image_reader = gdcm.ImageReader()
     image_reader.SetFileName(self.fname)
     if not image_reader.Read():
         raise IOError("Could not read DICOM image")
     pixel_array = self._gdcm_to_numpy(image_reader.GetImage())
     return pixel_array
示例#7
0
def read_dcm_slice_as_np2(filename, resolution_percentage=1.0):
    reader = gdcm.ImageReader()
    reader.SetFileName(filename)
    reader.Read()
    image = reader.GetImage()
    output = converters.gdcm_to_numpy(image)
    if resolution_percentage < 1.0:
        output = zoom(output, resolution_percentage)
    return output
示例#8
0
def TestKakadu(filename, kdu_expand):
    fn = gdcm.Filename(filename)
    testdir = fn.GetPath()
    testbasename = fn.GetName()
    ext = fn.GetExtension()
    #print ext
    #kakadu_path = '/home/mmalaterre/Software/Kakadu60'
    kakadu_path = os.path.dirname(kdu_expand)
    #kdu_expand = kakadu_path + '/kdu_expand'
    kdu_args = ' -quiet -i '
    output_dcm = testdir + '/kakadu/' + testbasename
    output_j2k = output_dcm + '.j2k'
    output_ppm = output_dcm + '.ppm'  #
    output_raw = output_dcm + '.rawl'  # FIXME: little endian only...
    kdu_expand += kdu_args + output_j2k + ' -o ' + output_raw
    # $ ./bin/gdcmraw -i .../TestImageChangeTransferSyntax2/012345.002.050.dcm -o toto.j2k
    executable_output_path = gdcm.GDCM_EXECUTABLE_OUTPUT_PATH
    gdcmraw = executable_output_path + '/gdcmraw'
    outputfilename = output_j2k
    gdcmraw_args = ' -i ' + filename + ' -o ' + outputfilename
    gdcmraw += gdcmraw_args
    #print gdcmraw
    ret = os.system(gdcmraw)
    #print "ret:",ret
    #print kdu_expand
    os.environ["LD_LIBRARY_PATH"] = kakadu_path
    ret = os.system(kdu_expand)
    # now need to skip the ppm header:
    dd_cmd = 'dd bs=15 skip=1 if=%s of = %s' % (output_ppm, output_raw)
    #print "ret:",ret
    md5 = gdcm.Testing.ComputeFileMD5(output_raw)
    # ok this is the md5 as computed after decompression using kdu_expand
    # let see if it match out previously (stored) md5:
    ref = gdcm.Testing.GetMD5FromFile(filename)
    #print ref
    retval = 0
    if ref != md5:
        img = gdcm.ImageReader()
        img.SetFileName(filename)
        img.Read()
        if img.GetImage().GetDimension(2) != 1:
            print("Test do not handle multiframes for now")
        elif img.GetImage().GetPixelFormat().GetSamplesPerPixel() != 1:
            print(
                "Test do not handle RGB for now. kdu_expand expand as RRR GGG BBB by default"
            )
        else:
            print("md5 are different: %s should be: %s for file %s" %
                  (md5, ref, filename))
            print("raw file was: %s" % (output_raw))
            retval = 1

    return retval
示例#9
0
def ProcessOneFilePublic(filename, outfilename, tmpfile):
    gdcm.ImageHelper.SetForceRescaleInterceptSlope(True)
    vtkreader = vtkgdcm.vtkGDCMImageReader()
    vtkreader.SetFileName(filename)
    vtkreader.Update()

    cast = vtk.vtkImageCast()
    cast.SetInput(vtkreader.GetOutput())
    cast.SetOutputScalarTypeToUnsignedShort()

    # vtkGDCMImageWriter does not support Sequence, so let's write a tmp file first:
    # Some operation will actually be discarded (we simply need a temp storage)
    vtkwriter = vtkgdcm.vtkGDCMImageWriter()
    vtkwriter.SetFileName(tmpfile)
    vtkwriter.SetMedicalImageProperties(vtkreader.GetMedicalImageProperties())
    vtkwriter.SetDirectionCosines(vtkreader.GetDirectionCosines())
    print "Format:", vtkreader.GetImageFormat()
    vtkwriter.SetImageFormat(vtkreader.GetImageFormat())
    vtkwriter.SetInput(cast.GetOutput())
    #vtkwriter.Update()
    vtkwriter.Write()

    # ok now rewrite the exact same file as the original (keep all info)
    # but use the Pixel Data Element from the written file
    tmpreader = gdcm.ImageReader()
    tmpreader.SetFileName(tmpfile)
    if not tmpreader.Read():
        sys.exit(1)

    reader = gdcm.Reader()
    reader.SetFileName(filename)
    if not reader.Read():
        sys.exit(1)

    # Make sure to remove Slope/Rescale to avoid re-execution
    ds = reader.GetFile().GetDataSet()
    tags = [
        gdcm.Tag(0x0028, 0x1052),
        gdcm.Tag(0x0028, 0x1053),
        gdcm.Tag(0x0028, 0x1053),
    ]
    for tag in tags:
        ds.Remove(tag)

    writer = gdcm.ImageWriter()
    writer.SetFileName(outfilename)
    # Pass image from vtk written file
    writer.SetImage(tmpreader.GetImage())
    # pass dataset from initial 'reader'
    writer.SetFile(reader.GetFile())
    if not writer.Write():
        sys.exit(1)
示例#10
0
 def __init__(self, dcm_path):
     try:
         self.dcm_path = dcm_path
         pygdcm.gdcm_Reader = gdcm.ImageReader()
         pygdcm.gdcm_Reader.SetFileName(self.dcm_path)
         file = pygdcm.gdcm_Reader.GetFile()
         self.dataset = file.GetDataSet()
         self.strFilter = gdcm.StringFilter()
         self.strFilter.SetFile(pygdcm.gdcm_Reader.GetFile())
         self.image_u16 = []
     except Exception as e:
         print(traceback.print_exc())
         return
示例#11
0
 def __init__(self, filename):
     self.image_reader = gdcm.ImageReader()
     self.image_reader.SetFileName(filename)
     self.reader = gdcm.Reader()
     self.reader.SetFileName(filename)
     if not self.reader.Read():
         raise DicomFileReadFailed("{} dicom file read failed.".format(
             filename))
     self.dicom_file = self.reader.GetFile()
     self.dicom_dataset = self.dicom_file.GetDataSet()
     self.dicom_header = self.dicom_file.GetHeader()
     if not self.image_reader.Read():
         raise DicomImageReadFailed("{} image read failed.".format(
             filename))
示例#12
0
文件: main.py 项目: ShurikAlive/DICOM
def readFile(filename):
    r = gdcm.ImageReader()
    r.SetFileName(filename)
    if not r.Read(): sys.exit(1)

    numpy_array = gdcm_to_numpy(r.GetImage())

    pilImage = Image.frombuffer('L', numpy_array.shape,
                                numpy_array.astype(numpy.uint8), 'raw', 'L', 0,
                                1)

    pilImage = ImageOps.autocontrast(pilImage, cutoff=.1)
    pilImage.save(filename + '.jpg')
    print(filename + '.jpg')
示例#13
0
def create_image_reader(filename):
    """Return a ``gdcm.ImageReader``.

    Parameters
    ----------
    filename: str or unicode
        The path to the DICOM dataset.

    Returns
    -------
    gdcm.ImageReader
    """
    image_reader = gdcm.ImageReader()
    image_reader.SetFileName(filename)
    return image_reader
示例#14
0
def _get_pixel_str_fileio(ds: "Dataset") -> str:
    """Return the pixel data from `ds` as a str.

    Used for GDCM < 2.8.8.

    Parameters
    ----------
    ds : pydicom.dataset.Dataset
        The dataset to create the str from.

    Returns
    -------
    str
        The UTF-8 encoded pixel data.
    """
    reader = gdcm.ImageReader()
    fname = getattr(ds, 'filename', None)
    if fname and isinstance(fname, str):
        reader.SetFileName(fname)
        if not reader.Read():
            raise TypeError("GDCM could not read DICOM image")

        return cast(str, reader.GetImage().GetBuffer())

    # Copy the relevant elements and write to a temporary file to avoid
    #   having to deal with all the possible objects the dataset may
    #   originate with
    new = ds.group_dataset(0x0028)
    new["PixelData"] = ds["PixelData"]  # avoid ambiguous VR
    new.file_meta = ds.file_meta
    with NamedTemporaryFile('wb', delete=False) as t:
        new.save_as(t)

    reader.SetFileName(t.name)
    if not reader.Read():
        raise TypeError("GDCM could not read DICOM image")

    pixel_str: str = reader.GetImage().GetBuffer()

    # Need to kill the gdcm.ImageReader to free file access
    reader = None
    os.remove(t.name)

    return pixel_str
示例#15
0
    def cn(self, file1):
        file2 = "tmp00.dcm"  # output filename

        reader = gdcm.ImageReader()
        reader.SetFileName(file1)
        reader.Read()
        change = gdcm.ImageChangeTransferSyntax()
        change.SetTransferSyntax(
            gdcm.TransferSyntax(gdcm.TransferSyntax.ImplicitVRLittleEndian))
        change.SetInput(reader.GetImage())
        change.Change()
        writer = gdcm.ImageWriter()
        writer.SetFileName(file2)
        writer.SetFile(reader.GetFile())
        writer.SetImage(change.GetOutput())
        writer.Write()
        zz = pydicom.read_file("tmp00.dcm")
        os.remove("tmp00.dcm")
        return zz
示例#16
0
 def Load(self, dirname):
     try:
         if not XFile.PathExists(dirname):
             raise DIVError(-1)
         files = XFile.GetList(dirname, '*.' + DIV.DEFAULT_EXTENSION)
         if files is None or len(files) == 0:
             raise DIVError(-2)
         vol = None
         vdim = None
         for dfile in sorted(files):
             dicom = gdcm.ImageReader()
             dicom.SetFileName(dirname + '/' + dfile)
             if not dicom.Read():
                 raise DIVError(-3)
             image = dicom.GetImage()
             if vdim is None:
                 vdim = image.GetDimensions()  # Image dimensions
                 fmt = image.GetPixelFormat()  # Pixel format
                 vs = image.GetSpacing()  # Voxel size
                 vdim.append(len(files))
                 dt = DIV_DTYPES[fmt.GetScalarType()]
             raw = np.frombuffer(image.GetBuffer(), dtype=dt)
             vol = raw if vol is None else np.append(vol, raw)
         xdim, ydim, zdim = vdim
         vol = vol.reshape((zdim, ydim, xdim))
         vu = Volume.VOXEL_UNITS['mm']
         cl = [0] * 8
         nc = 1
     except DIVError as err:
         print err.message % filename, err.info
         raise
     except Exception:
         raise
     else:
         self.data = vol
         self.xdim = xdim
         self.ydim = ydim
         self.zdim = zdim
         self.vdim = vdim
         self.vunit = vu
         self.vsize = vs
         self.nchan = nc
         self.clist = cl
示例#17
0
def dc(inputFile, outputFile):
	reader = gdcm.ImageReader()
	reader.SetFileName(inputFile)

	if not reader.Read():
		sys.exit(1)

	change = gdcm.ImageChangeTransferSyntax()
	change.SetTransferSyntax( gdcm.TransferSyntax(gdcm.TransferSyntax.ImplicitVRLittleEndian) )
	change.SetInput( reader.GetImage() )
	if not change.Change():
		sys.exit(1)

	writer = gdcm.ImageWriter()
	writer.SetFileName(outputFile)
	writer.SetFile( reader.GetFile() )
	writer.SetImage( change.GetOutput() )

	if not writer.Write():
		sys.exit(1)
示例#18
0
def create_image_reader(filename):
    """Create a gdcm.ImageReader

    Parameters
    ----------
    filename: str or unicode (Python 2)

    Returns
    -------
    gdcm.ImageReader
    """
    image_reader = gdcm.ImageReader()
    if compat.in_py2:
        if isinstance(filename, unicode):
            image_reader.SetFileName(
                filename.encode(sys.getfilesystemencoding()))
        else:
            image_reader.SetFileName(filename)
    else:
        image_reader.SetFileName(filename)
    return image_reader
示例#19
0
def create_image_reader(filename):
    """Return a ``gdcm.ImageReader``.

    Parameters
    ----------
    filename: str or unicode
        The path to the DICOM dataset.

    Returns
    -------
    gdcm.ImageReader
    """
    image_reader = gdcm.ImageReader()
    if compat.in_py2:
        if isinstance(filename, unicode):
            image_reader.SetFileName(
                filename.encode(sys.getfilesystemencoding()))
        else:
            image_reader.SetFileName(filename)
    else:
        image_reader.SetFileName(filename)
    return image_reader
示例#20
0
def method2(file1, file2):

    reader = gdcm.ImageReader()
    reader.SetFileName(file1)

    if not reader.Read():
        sys.exit(1)

    change = gdcm.ImageChangeTransferSyntax()
    change.SetTransferSyntax(
        gdcm.TransferSyntax(gdcm.TransferSyntax.ImplicitVRLittleEndian))
    change.SetInput(reader.GetImage())
    if not change.Change():
        sys.exit(1)

    writer = gdcm.ImageWriter()
    writer.SetFileName(file2)
    writer.SetFile(reader.GetFile())
    writer.SetImage(change.GetOutput())

    if not writer.Write():
        raise ValueError
示例#21
0
def ExecuteInformation(reader, filename, dimz=1):
    import gdcm
    reffile = filename  # filenames.GetValue(0) # Take first image as reference
    #print reader
    r = gdcm.ImageReader()
    r.SetFileName(reffile)
    success = r.Read()
    assert success
    #print r.GetImage().Print()
    image = r.GetImage()
    assert image.GetNumberOfDimensions() == 2 or image.GetNumberOfDimensions(
    ) == 3
    dims = [0, 0, 0]
    dims[0] = image.GetDimension(0)
    dims[1] = image.GetDimension(1)
    dims[2] = dimz  # filenames.GetNumberOfValues()
    #print dims
    #print image.GetPixelFormat().GetTPixelFormat()
    pixelformat = image.GetPixelFormat().GetScalarType()
    datascalartype = vtkType.VTK_VOID  # dummy should not happen
    if pixelformat == gdcm.PixelFormat.INT8:
        datascalartype = vtkType.VTK_SIGNED_CHAR
    elif pixelformat == gdcm.PixelFormat.UINT8:
        datascalartype = vtkType.VTK_UNSIGNED_CHAR
    elif pixelformat == gdcm.PixelFormat.INT16:
        datascalartype = vtkType.VTK_SHORT
    elif pixelformat == gdcm.PixelFormat.UINT16:
        datascalartype = vtkType.VTK_UNSIGNED_SHORT
    else:
        print "Unhandled PixelFormat: ", pixelformat
        sys.exit(1)
    #print datascalartype
    numberOfScalarComponents = image.GetPixelFormat().GetSamplesPerPixel()
    #print numberOfScalarComponents
    #print gdcm.PhotometricInterpretation.GetPIString( image.GetPhotometricInterpretation().PIType() )
    #reader.SetDataExtent( dataextent );
    reader.SetDataExtent(0, dims[0] - 1, 0, dims[1] - 1, 0, dims[2] - 1)
    reader.SetDataScalarType(datascalartype)
    reader.SetNumberOfScalarComponents(numberOfScalarComponents)
示例#22
0
def open_image(path, verbose=True):
    """
    Open a two- or three-dimensional DICOM image at the given <path>.
    
    Return a tuple (ireader, data) where <ireader> represents a
    <gdcm.ImageReader> reference to the image as returned by the GDCM library,
    and <data> holds the actual image data in a Numpy array.
    
    Note that the image data as a <gdcm.Image> instance can be obtained from
    the <ireader> via <ireader.GetImage()>. However, the image instance is
    only valid as long as the <ireader> is not destroyed. This is the reason
    why the <ImageReader> rather than the <Image> instance is returned here.
    
    If unsuccessful, an <IOError> will be raised.
    """
    # Create a reader for the image
    reader = gdcm.ImageReader()
    reader.SetFileName(path)
    # Try to actually read it
    read_success = reader.Read()
    if not read_success:
        raise IOError("Error opening dicom-file.")
    image = reader.GetImage()
    # Convert to Numpy array
    try:
        data = __to_array(image)
    except ValueError:
        # Re-raise as IOError with complete traceback
        import sys
        (value, traceback) = sys.exc_info()[1:]
        raise (IOError, value, traceback)
    if verbose:
        print "Image loaded:", path
        print "Meta data:"
        print image
    return (reader, data)
示例#23
0
    def run(self):

        grouper = self.grouper
        reader = gdcm.ImageReader()
        reader.SetFileName(self.filepath)
        if (reader.Read()):
            file = reader.GetFile()

            # Retrieve data set
            dataSet = file.GetDataSet()

            # Retrieve header
            header = file.GetHeader()
            stf = gdcm.StringFilter()

            field_dict = {}
            data_dict = {}

            tag = gdcm.Tag(0x0008, 0x0005)
            ds = reader.GetFile().GetDataSet()
            if ds.FindDataElement(tag):
                encoding_value = str(
                    ds.GetDataElement(tag).GetValue()).split('\\')[0]

                if encoding_value.startswith("Loaded"):
                    encoding = "ISO_IR 100"
                else:
                    try:
                        encoding = const.DICOM_ENCODING_TO_PYTHON[
                            encoding_value]
                    except KeyError:
                        encoding = 'ISO_IR 100'
            else:
                encoding = "ISO_IR 100"

            # Iterate through the Header
            iterator = header.GetDES().begin()
            while (not iterator.equal(header.GetDES().end())):
                dataElement = iterator.next()
                stf.SetFile(file)
                tag = dataElement.GetTag()
                data = stf.ToStringPair(tag)
                stag = tag.PrintAsPipeSeparatedString()

                group = str(tag.GetGroup())
                field = str(tag.GetElement())

                tag_labels[stag] = data[0]

                if not group in data_dict.keys():
                    data_dict[group] = {}

                if not (utils.VerifyInvalidPListCharacter(data[1])):
                    data_dict[group][field] = data[1].decode(encoding)
                else:
                    data_dict[group][field] = "Invalid Character"

            # Iterate through the Data set
            iterator = dataSet.GetDES().begin()
            while (not iterator.equal(dataSet.GetDES().end())):
                dataElement = iterator.next()

                stf.SetFile(file)
                tag = dataElement.GetTag()
                data = stf.ToStringPair(tag)
                stag = tag.PrintAsPipeSeparatedString()

                group = str(tag.GetGroup())
                field = str(tag.GetElement())

                tag_labels[stag] = data[0]

                if not group in data_dict.keys():
                    data_dict[group] = {}

                if not (utils.VerifyInvalidPListCharacter(data[1])):
                    data_dict[group][field] = data[1].decode(
                        encoding, 'replace')
                else:
                    data_dict[group][field] = "Invalid Character"

            # -------------- To Create DICOM Thumbnail -----------
            rvtk = vtkgdcm.vtkGDCMImageReader()
            rvtk.SetFileName(self.filepath)
            rvtk.Update()

            try:
                data = data_dict[str(0x028)][str(0x1050)]
                level = [float(value) for value in data.split('\\')][0]
                data = data_dict[str(0x028)][str(0x1051)]
                window = [float(value) for value in data.split('\\')][0]
            except (KeyError):
                level = 300.0
                window = 2000.0

            colorer = vtk.vtkImageMapToWindowLevelColors()
            colorer.SetInputConnection(rvtk.GetOutputPort())
            colorer.SetWindow(float(window))
            colorer.SetLevel(float(level))
            colorer.SetOutputFormatToRGB()
            colorer.Update()

            resample = vtk.vtkImageResample()
            resample.SetInputConnection(colorer.GetOutputPort())
            resample.SetAxisMagnificationFactor(0, 0.25)
            resample.SetAxisMagnificationFactor(1, 0.25)
            resample.SetAxisMagnificationFactor(2, 1)
            resample.Update()

            thumbnail_path = tempfile.mktemp()

            write_png = vtk.vtkPNGWriter()
            write_png.SetInputConnection(resample.GetOutputPort())
            write_png.SetFileName(thumbnail_path)
            write_png.Write()

            #------ Verify the orientation --------------------------------

            img = reader.GetImage()
            direc_cosines = img.GetDirectionCosines()
            orientation = gdcm.Orientation()
            try:
                type = orientation.GetType(tuple(direc_cosines))
            except TypeError:
                type = orientation.GetType(direc_cosines)
            label = orientation.GetLabel(type)

            # ----------   Refactory --------------------------------------
            data_dict['invesalius'] = {'orientation_label': label}

            # -------------------------------------------------------------
            dict_file[self.filepath] = data_dict

            #----------  Verify is DICOMDir -------------------------------
            is_dicom_dir = 1
            try:
                if (data_dict[str(0x002)][str(0x002)] !=
                        "1.2.840.10008.1.3.10"):  #DICOMDIR
                    is_dicom_dir = 0
            except (KeyError):
                is_dicom_dir = 0

            if not (is_dicom_dir):
                parser = dicom.Parser()
                parser.SetDataImage(dict_file[self.filepath], self.filepath,
                                    thumbnail_path)

                dcm = dicom.Dicom()
                #self.l.acquire()
                dcm.SetParser(parser)
                grouper.AddFile(dcm)
示例#24
0
  It will produce a 'merge.dcm' output file, which contains all meta information from input1.dcm
  and copy the Stored Pixel values from input2.dcm
  This script even works when input2.dcm is a Secondary Capture and does not contains information
  such as IOP and IPP...
"""

import sys
import gdcm

if __name__ == "__main__":

  file1 = sys.argv[1]
  file2 = sys.argv[2]

  r1 = gdcm.ImageReader()
  r1.SetFileName( file1 )
  if not r1.Read():
    sys.exit(1)

  r2 = gdcm.ImageReader()
  r2.SetFileName( file2 )
  if not r2.Read():
    sys.exit(1)

  # Image from r2 could be Secondary Capture and thus would not contains neither IPP nor IOP
  # Instead always prefer to only copy the Raw Data Element.
  # Warning ! Image need to be identical ! Only the value of Stored Pixel can be different.
  r1.GetImage().SetDataElement( r2.GetImage().GetDataElement() )

  w = gdcm.ImageWriter()
示例#25
0
############################################################################
"""
Usage:

 python DecompressImage.py gdcmData/012345.002.050.dcm decompress.dcm
"""

import gdcm
import sys

if __name__ == "__main__":

    file1 = sys.argv[1]
    file2 = sys.argv[2]

    r = gdcm.ImageReader()
    r.SetFileName(file1)
    if not r.Read():
        sys.exit(1)

    # check GetFragment API:
    pd = r.GetFile().GetDataSet().GetDataElement(gdcm.Tag(0x7fe0, 0x0010))
    frags = pd.GetSequenceOfFragments()
    frags.GetFragment(0)

    ir = r.GetImage()
    w = gdcm.ImageWriter()
    image = w.GetImage()

    image.SetNumberOfDimensions(ir.GetNumberOfDimensions())
    dims = ir.GetDimensions()
示例#26
0
    def loadImage_gdcm(filename):
        """Load a DICOM image into a numpy array.

        This function uses the python-gdcm module to load a DICOM image
        into a numpy array. See also :func:`loadImage_dicom` for an
        equivalent using python-dicom.

        Parameters:

        - `file`: the name of a DICOM image file

        Returns a 3D array with the pixel data of all the images. The first
          axis is the `z` value, the last the `x`.

        As a side effect, this function sets the global variable `_dicom_spacing`
        to a (3,) array with the pixel/slice spacing factors, in order (x,y,z).
        """
        import gdcm

        def get_gdcm_to_numpy_typemap():
            """Returns the GDCM Pixel Format to numpy array type mapping."""
            _gdcm_np = {
                gdcm.PixelFormat.UINT8:
                np.int8,
                gdcm.PixelFormat.INT8:
                np.uint8,
                #gdcm.PixelFormat.UINT12 :np.uint12,
                #gdcm.PixelFormat.INT12  :np.int12,
                gdcm.PixelFormat.UINT16:
                np.uint16,
                gdcm.PixelFormat.INT16:
                np.int16,
                gdcm.PixelFormat.UINT32:
                np.uint32,
                gdcm.PixelFormat.INT32:
                np.int32,
                #gdcm.PixelFormat.FLOAT16:np.float16,
                gdcm.PixelFormat.FLOAT32:
                np.float32,
                gdcm.PixelFormat.FLOAT64:
                np.float64
            }
            return _gdcm_np

        def get_numpy_array_type(gdcm_pixel_format):
            """Returns a numpy array typecode given a GDCM Pixel Format."""
            return get_gdcm_to_numpy_typemap()[gdcm_pixel_format]

        def gdcm_to_numpy(image):
            """Convert a GDCM image to a numpy array.

            """
            fmt = image.GetPixelFormat()

            if fmt.GetScalarType() not in get_gdcm_to_numpy_typemap().keys():
                raise ValueError, "Unsupported Pixel Format\n%s" % fmt

            shape = (image.GetDimension(0), image.GetDimension(1))
            if image.GetNumberOfDimensions() == 3:
                shape = shape + (image.GetDimension(2), )
            if fmt.GetSamplesPerPixel() != 1:
                raise ValueError, "Can not read images with multiple samples per pixel."

            dtype = get_numpy_array_type(fmt.GetScalarType())
            gdcm_array = image.GetBuffer()
            data = np.frombuffer(gdcm_array, dtype=dtype).reshape(shape)
            spacing = np.array(image.GetSpacing())
            return data, spacing

        global _dicom_spacing
        r = gdcm.ImageReader()
        r.SetFileName(filename)
        if not r.Read():
            raise ValueError, "Could not read image file '%s'" % filename
        pix, _dicom_spacing = gdcm_to_numpy(r.GetImage())
        return pix
示例#27
0
    def _pixel_data_numpy(self):
        """Return a NumPy array of the pixel data if NumPy is available.
        Falls back to GDCM in case of unsupported transfer syntaxes.

        Raises
        ------
        TypeError
            If there is no pixel data or not a supported data type
        ImportError
            If NumPy isn't found, or in the case of fallback, if GDCM isn't found.

        Returns
        -------
        NumPy array
        """
        if not self._is_uncompressed_transfer_syntax():
            if not have_gdcm:
                raise NotImplementedError(
                    "Pixel Data is compressed in a format pydicom does not yet handle. Cannot return array. Pydicom might be able to convert the pixel data using GDCM if it is installed."
                )
            elif not self.filename:
                raise NotImplementedError(
                    "GDCM is only supported when the dataset has been created with a filename."
                )
        if not have_numpy:
            msg = "The Numpy package is required to use pixel_array, and numpy could not be imported."
            raise ImportError(msg)
        if 'PixelData' not in self:
            raise TypeError("No pixel data found in this dataset.")

        # There are two cases:
        # 1) uncompressed PixelData -> use numpy
        # 2) compressed PixelData, filename is available and GDCM is available -> use GDCM

        is_single_bit = False
        if self._is_uncompressed_transfer_syntax():
            # Make NumPy format code, e.g. "uint16", "int32" etc
            # from two pieces of info:
            #    self.PixelRepresentation -- 0 for unsigned, 1 for signed;
            #    self.BitsAllocated -- 8, 16, or 32
            format_str = '%sint%d' % (
                ('u', '')[self.PixelRepresentation], self.BitsAllocated)
            # Handle SINGLEBIT case
            if self.BitsAllocated == 1:
                is_single_bit = True
                format_str = "uint8"
            try:
                numpy_dtype = numpy.dtype(format_str)
            except TypeError:
                msg = ("Data type not understood by NumPy: "
                       "format='%s', PixelRepresentation=%d, BitsAllocated=%d")
                raise TypeError(
                    msg %
                    (format_str, self.PixelRepresentation, self.BitsAllocated))

            if (self.is_little_endian !=
                    sys_is_little_endian) and not is_single_bit:
                numpy_dtype = numpy_dtype.newbyteorder('S')

            pixel_bytearray = self.PixelData
        elif have_gdcm and self.filename:
            # read the file using GDCM
            # FIXME this should just use self.PixelData instead of self.filename
            #       but it is unclear how this should be achieved using GDCM
            gdcm_image_reader = gdcm.ImageReader()
            gdcm_image_reader.SetFileName(self.filename)
            if not gdcm_image_reader.Read():
                raise TypeError("GDCM could not read DICOM image")
            gdcm_image = gdcm_image_reader.GetImage()

            # determine the correct numpy datatype
            gdcm_numpy_typemap = {
                gdcm.PixelFormat.INT8:
                numpy.int8,
                gdcm.PixelFormat.UINT8:
                numpy.uint8,
                gdcm.PixelFormat.UINT16:
                numpy.uint16,
                gdcm.PixelFormat.INT16:
                numpy.int16,
                gdcm.PixelFormat.UINT32:
                numpy.uint32,
                gdcm.PixelFormat.INT32:
                numpy.int32,
                gdcm.PixelFormat.FLOAT32:
                numpy.float32,
                gdcm.PixelFormat.FLOAT64:
                numpy.float64,
                # Use numpy uint8 for single bits
                gdcm.PixelFormat.SINGLEBIT:
                numpy.uint8
            }
            gdcm_pixel_format = gdcm_image.GetPixelFormat().GetScalarType()
            if gdcm_pixel_format in gdcm_numpy_typemap:
                numpy_dtype = gdcm_numpy_typemap[gdcm_pixel_format]
            else:
                raise TypeError(
                    '{0} is not a GDCM supported pixel format'.format(
                        gdcm_pixel_format))

            # GDCM returns char* as type str. Under Python 2 `str` are
            # byte arrays by default. Python 3 decodes this to
            # unicode strings by default.
            # The SWIG docs mention that they always decode byte streams
            # as utf-8 strings for Python 3, with the `surrogateescape`
            # error handler configured.
            # Therefore, we can encode them back to their original bytearray
            # representation on Python 3 by using the same parameters.
            pixel_bytearray = gdcm_image.GetBuffer()
            if sys.version_info >= (3, 0):
                pixel_bytearray = pixel_bytearray.encode(
                    "utf-8", "surrogateescape")

            # if GDCM indicates that a byte swap is in order, make sure to inform numpy as well
            if gdcm_image.GetNeedByteSwap():
                numpy_dtype = numpy_dtype.newbyteorder('S')

            # Here we need to be careful because in some cases, GDCM reads a
            # buffer that is too large, so we need to make sure we only include
            # the first n_rows * n_columns * dtype_size bytes.

            # Only check padding in case other format than SingleBIT
            if gdcm_pixel_format != gdcm.PixelFormat.SINGLEBIT:

                n_bytes = self.Rows * self.Columns * numpy.dtype(
                    numpy_dtype).itemsize

                if len(pixel_bytearray) > n_bytes:

                    # We make sure that all the bytes after are in fact zeros
                    padding = pixel_bytearray[n_bytes:]
                    if numpy.any(numpy.fromstring(padding, numpy.byte)):
                        pixel_bytearray = pixel_bytearray[:n_bytes]
                    else:
                        # We revert to the old behavior which should then result in a
                        # Numpy error later on.
                        pass
            else:
                is_single_bit = True
        #
        try:
            pixel_array = numpy.fromstring(pixel_bytearray, dtype=numpy_dtype)
        except TypeError:
            pixel_array = numpy.frombuffer(pixel_bytearray, dtype=numpy_dtype)

        # Handle SINGLEBIT encoding
        if is_single_bit:
            pixel_array = numpy.unpackbits(pixel_array[::-1])

        # Note the following reshape operations return a new *view* onto pixel_array, but don't copy the data
        if 'NumberOfFrames' in self and self.NumberOfFrames > 1:
            if self.SamplesPerPixel > 1:
                # TODO: Handle Planar Configuration attribute
                assert self.PlanarConfiguration == 0
                pixel_array = pixel_array.reshape(self.NumberOfFrames,
                                                  self.Rows, self.Columns,
                                                  self.SamplesPerPixel)
            else:
                pixel_array = pixel_array.reshape(self.NumberOfFrames,
                                                  self.Rows, self.Columns)
        else:
            if self.SamplesPerPixel > 1:
                if self.BitsAllocated == 8:
                    if self.PlanarConfiguration == 0:
                        pixel_array = pixel_array.reshape(
                            self.Rows, self.Columns, self.SamplesPerPixel)
                    else:
                        pixel_array = pixel_array.reshape(
                            self.SamplesPerPixel, self.Rows, self.Columns)
                        pixel_array = pixel_array.transpose(1, 2, 0)
                else:
                    raise NotImplementedError(
                        "This code only handles SamplesPerPixel > 1 if Bits Allocated = 8"
                    )
            else:
                pixel_array = pixel_array.reshape(self.Rows, self.Columns)
        return pixel_array
示例#28
0
def get_pixeldata(dicom_dataset):
    """
    Use the GDCM package to decode the PixelData attribute

    Returns
    -------
    numpy.ndarray

        A correctly sized (but not shaped) numpy array
        of the entire data volume

    Raises
    ------
    ImportError
        if the required packages are not available

    TypeError
        if the image could not be read by GDCM
        if the pixel data type is unsupported

    AttributeError
        if the decoded amount of data does not match the expected amount
    """

    # read the file using GDCM
    # FIXME this should just use dicom_dataset.PixelData
    # instead of dicom_dataset.filename
    #       but it is unclear how this should be achieved using GDCM
    if not can_use_gdcm:
        msg = ("GDCM requires both the gdcm package and numpy "
               "and one or more could not be imported")
        raise ImportError(msg)

    gdcm_image_reader = gdcm.ImageReader()
    if compat.in_py2:
        if isinstance(dicom_dataset.filename, unicode):
            gdcm_image_reader.SetFileName(
                dicom_dataset.filename.encode(sys.getfilesystemencoding()))
        else:
            gdcm_image_reader.SetFileName(dicom_dataset.filename)
    else:
        # python 3
        gdcm_image_reader.SetFileName(dicom_dataset.filename)

    if not gdcm_image_reader.Read():
        raise TypeError("GDCM could not read DICOM image")

    gdcm_image = gdcm_image_reader.GetImage()

    # determine the correct numpy datatype
    gdcm_numpy_typemap = {
        gdcm.PixelFormat.INT8: numpy.int8,
        gdcm.PixelFormat.UINT8: numpy.uint8,
        gdcm.PixelFormat.UINT16: numpy.uint16,
        gdcm.PixelFormat.INT16: numpy.int16,
        gdcm.PixelFormat.UINT32: numpy.uint32,
        gdcm.PixelFormat.INT32: numpy.int32,
        gdcm.PixelFormat.FLOAT32: numpy.float32,
        gdcm.PixelFormat.FLOAT64: numpy.float64
    }
    gdcm_pixel_format = gdcm_image.GetPixelFormat().GetScalarType()
    if gdcm_pixel_format in gdcm_numpy_typemap:
        numpy_dtype = gdcm_numpy_typemap[gdcm_pixel_format]
    else:
        raise TypeError('{0} is not a GDCM supported '
                        'pixel format'.format(gdcm_pixel_format))

    # GDCM returns char* as type str. Under Python 2 `str` are
    # byte arrays by default. Python 3 decodes this to
    # unicode strings by default.
    # The SWIG docs mention that they always decode byte streams
    # as utf-8 strings for Python 3, with the `surrogateescape`
    # error handler configured.
    # Therefore, we can encode them back to their original bytearray
    # representation on Python 3 by using the same parameters.
    pixel_bytearray = gdcm_image.GetBuffer()
    if sys.version_info >= (3, 0):
        pixel_bytearray = pixel_bytearray.encode("utf-8", "surrogateescape")

    # if GDCM indicates that a byte swap is in order, make
    #   sure to inform numpy as well
    if gdcm_image.GetNeedByteSwap():
        numpy_dtype = numpy_dtype.newbyteorder('S')

    # Here we need to be careful because in some cases, GDCM reads a
    # buffer that is too large, so we need to make sure we only include
    # the first n_rows * n_columns * dtype_size bytes.

    n_bytes = (dicom_dataset.Rows * dicom_dataset.Columns *
               numpy.dtype(numpy_dtype).itemsize)
    try:
        n_bytes *= dicom_dataset.NumberOfFrames
    except Exception:
        pass
    try:
        n_bytes *= dicom_dataset.SamplesPerPixel
    except Exception:
        pass
    if len(pixel_bytearray) > n_bytes:
        # We make sure that all the bytes after are in fact zeros
        padding = pixel_bytearray[n_bytes:]
        if numpy.any(numpy.frombuffer(padding, numpy.byte)):
            pixel_bytearray = pixel_bytearray[:n_bytes]
        else:
            # We revert to the old behavior which should then result
            #   in a Numpy error later on.
            pass
    pixel_array = numpy.frombuffer(pixel_bytearray, dtype=numpy_dtype)
    length_of_pixel_array = pixel_array.nbytes
    expected_length = dicom_dataset.Rows * dicom_dataset.Columns

    expected_length *= dicom_dataset.get("NumberOfFrames", 1)
    expected_length *= dicom_dataset.get("SamplesPerPixel", 1)

    if dicom_dataset.BitsAllocated > 8:
        expected_length *= (dicom_dataset.BitsAllocated // 8)
    if length_of_pixel_array != expected_length:
        raise AttributeError("Amount of pixel data %d does "
                             "not match the expected data %d" %
                             (length_of_pixel_array, expected_length))
    if should_change_PhotometricInterpretation_to_RGB(dicom_dataset):
        dicom_dataset.PhotometricInterpretation = "RGB"
    return pixel_array
示例#29
0
def TestImageRead(filename, verbose=False):
    r = gdcm.ImageReader()
    r.SetFileName(filename)
    success = r.Read()
    if verbose: print r.GetImage()
    return success
示例#30
0
    def run(self):
        grouper = self.grouper
        reader = gdcm.ImageReader()
        if _has_win32api:
            try:
                reader.SetFileName(
                    utils.encode(win32api.GetShortPathName(self.filepath),
                                 const.FS_ENCODE))
            except TypeError:
                reader.SetFileName(win32api.GetShortPathName(self.filepath))
        else:
            try:
                reader.SetFileName(utils.encode(self.filepath,
                                                const.FS_ENCODE))
            except TypeError:
                reader.SetFileName(self.filepath)
        if (reader.Read()):
            file = reader.GetFile()
            # Retrieve data set
            dataSet = file.GetDataSet()
            # Retrieve header
            header = file.GetHeader()
            stf = gdcm.StringFilter()
            stf.SetFile(file)

            field_dict = {}
            data_dict = {}

            tag = gdcm.Tag(0x0008, 0x0005)
            ds = reader.GetFile().GetDataSet()
            if ds.FindDataElement(tag):
                encoding_value = str(
                    ds.GetDataElement(tag).GetValue()).split('\\')[0]

                if encoding_value.startswith("Loaded"):
                    encoding = "ISO_IR 100"
                else:
                    try:
                        encoding = const.DICOM_ENCODING_TO_PYTHON[
                            encoding_value]
                    except KeyError:
                        encoding = 'ISO_IR 100'
            else:
                encoding = "ISO_IR 100"

            # Iterate through the Header
            iterator = header.GetDES().begin()
            while (not iterator.equal(header.GetDES().end())):
                dataElement = iterator.next()
                if not dataElement.IsUndefinedLength():
                    tag = dataElement.GetTag()
                    data = stf.ToStringPair(tag)
                    stag = tag.PrintAsPipeSeparatedString()

                    group = str(tag.GetGroup())
                    field = str(tag.GetElement())

                    tag_labels[stag] = data[0]

                    if not group in data_dict.keys():
                        data_dict[group] = {}

                    if not (utils.VerifyInvalidPListCharacter(data[1])):
                        data_dict[group][field] = utils.decode(
                            data[1], encoding)
                    else:
                        data_dict[group][field] = "Invalid Character"

            # Iterate through the Data set
            iterator = dataSet.GetDES().begin()
            while (not iterator.equal(dataSet.GetDES().end())):
                dataElement = iterator.next()
                if not dataElement.IsUndefinedLength():
                    tag = dataElement.GetTag()
                    #  if (tag.GetGroup() == 0x0009 and tag.GetElement() == 0x10e3) \
                    #  or (tag.GetGroup() == 0x0043 and tag.GetElement() == 0x1027):
                    #  continue
                    data = stf.ToStringPair(tag)
                    stag = tag.PrintAsPipeSeparatedString()

                    group = str(tag.GetGroup())
                    field = str(tag.GetElement())

                    tag_labels[stag] = data[0]

                    if not group in data_dict.keys():
                        data_dict[group] = {}

                    if not (utils.VerifyInvalidPListCharacter(data[1])):
                        data_dict[group][field] = utils.decode(
                            data[1], encoding, 'replace')
                    else:
                        data_dict[group][field] = "Invalid Character"

            # -------------- To Create DICOM Thumbnail -----------

            try:
                data = data_dict[str(0x028)][str(0x1050)]
                level = [float(value) for value in data.split('\\')][0]
                data = data_dict[str(0x028)][str(0x1051)]
                window = [float(value) for value in data.split('\\')][0]
            except (KeyError, ValueError):
                level = None
                window = None

            if _has_win32api:
                thumbnail_path = imagedata_utils.create_dicom_thumbnails(
                    win32api.GetShortPathName(self.filepath), window, level)
            else:
                thumbnail_path = imagedata_utils.create_dicom_thumbnails(
                    self.filepath, window, level)

            #------ Verify the orientation --------------------------------

            img = reader.GetImage()
            direc_cosines = img.GetDirectionCosines()
            orientation = gdcm.Orientation()
            try:
                _type = orientation.GetType(tuple(direc_cosines))
            except TypeError:
                _type = orientation.GetType(direc_cosines)
            label = orientation.GetLabel(_type)

            # ----------   Refactory --------------------------------------
            data_dict['invesalius'] = {'orientation_label': label}

            # -------------------------------------------------------------
            dict_file[self.filepath] = data_dict

            #----------  Verify is DICOMDir -------------------------------
            is_dicom_dir = 1
            try:
                if (data_dict[str(0x002)][str(0x002)] !=
                        "1.2.840.10008.1.3.10"):  #DICOMDIR
                    is_dicom_dir = 0
            except (KeyError):
                is_dicom_dir = 0

            if not (is_dicom_dir):
                parser = dicom.Parser()
                parser.SetDataImage(dict_file[self.filepath], self.filepath,
                                    thumbnail_path)

                dcm = dicom.Dicom()
                #self.l.acquire()
                dcm.SetParser(parser)
                grouper.AddFile(dcm)