Exemplo n.º 1
0
def extractStudyDetails(inputImageFile):
    """Reads and extracts Patient's Basic Info from a DICOM file.
    """
    studyList = []
    dicomfile = inputImageFile
    tracker = set()
    trackerID=''
    for i, dfile in enumerate(dicomfile):

        studyDetails = {}
        ds = dicomio.read_file(dfile)

        if ds[0x00200010]:
           # print(ds[0x00200010])
            trackerID = str(ds.StudyID)
            if trackerID in tracker:
                ''
            else:
                studyDetails["StudyID"]= ds.StudyID
                studyDetails["StudyDescription"]=ds.StudyDescription
                studyDetails["StudyDate"]= datetime.strptime(ds.StudyDate, '%Y%m%d')
                studyDetails["PatientID"]=ds.PatientID
                tracker.add(str(ds.StudyID))

                studyList.append(studyDetails)
        else:
            ''

    return studyList
Exemplo n.º 2
0
def run(path):
    # Используем Python одним потоком
    start_time = time.time()
    paths = find_all_files(path)
    for file_path in paths:
        if os.path.isdir(file_path): continue
        dcm = dicomio.read_file(file_path, specific_tags=REQUIRED_TAGS)
        tags_py = {
            t: dcm.get(t) if t in dcm else DEFAULT_TAG_VAL
            for t in REQUIRED_TAGS
        }
    py_long = time.time() - start_time
    # ----------------------------------------

    # Используем Rust
    start_time = time.time()
    _ = py_dcm_finder_rs.load_dcm_files_in_dir(path, REQUIRED_TAGS,
                                               DEFAULT_TAG_VAL)
    rust_long = time.time() - start_time
    # ----------------------------------------

    # Используем Python c multiprocessing
    start_time = time.time()
    find_and_read_dcm_in_dir_multiproc(path)
    multi_py_long = time.time() - start_time
    # ----------------------------------------

    print(f"Всего файлов в папке: {len(paths)}")
    print("─" * 42)
    print(f"| {'Python одним процессом':25} | {f'{py_long:.5f}':10} |")
    print(f"| {'Rust вызванный из python':25} | {f'{rust_long:.5f}':10} |")
    print(f"| {'Python мульти процес.':25} | {f'{multi_py_long:.5f}':10} |")
    print("─" * 42)
Exemplo n.º 3
0
 def __init__(self, dataset, memmap_pixel_array=False):
     self.memmap_pixel_array = memmap_pixel_array
     if isinstance(dataset, Dataset):
         self.ds = dataset
     elif isinstance(dataset, (string_types, BytesIO)):
         try:
             with open(dataset, "rb") as fp:
                 self.ds = read_file(fp,
                                     defer_size=100,
                                     force=True,
                                     stop_before_pixels=memmap_pixel_array)
                 if memmap_pixel_array:
                     self.offset = fp.tell() + 8
         except:
             # Raise the error for the calling method to handle
             raise
         else:
             # Sometimes DICOM files may not have headers,
             # but they should always have a SOPClassUID
             # to declare what type of file it is.
             # If the file doesn't have a SOPClassUID,
             # then it probably isn't DICOM.
             if not "SOPClassUID" in self.ds:
                 raise AttributeError
     else:
         raise AttributeError
     if memmap_pixel_array:
         self.filename = dataset
         self.pixel_array = self.get_pixel_array
     else:
         if "PixelData" in self.ds:
             self.pixel_array = self.ds.pixel_array
Exemplo n.º 4
0
def extractPatientDetails(inputImageFile):
    """Reads and extracts Patient's Basic Info from a DICOM file.
    """
    PatientList = []
    dicomfile = inputImageFile
    tracker = set()

    for i, dfile in enumerate(dicomfile):

        patientDetails = {}
        ds = dicomio.read_file(dfile)
        trackerID = str(ds.PatientID)
        if trackerID in tracker:
            ''
        else:
            patientDetails["PatientID"]=ds.PatientID
            patientDetails["PatientName"]= str.replace(str(ds.PatientName),'^',' ')
            patientDetails["PatientSex"]=ds.PatientSex
            if ds[0x00101010]:
                patientDetails["PatientReportedAge"]=ds.PatientAge
            else:
                patientDetails["PatientReportedAge"]=''

            dob = datetime.strptime(ds.PatientBirthDate , '%Y%m%d')
            sod =  datetime.strptime(ds.StudyDate, '%Y%m%d')
            patientDetails["PatientBirthDate"]= dob

            patientDetails['Age_Days']= str.replace(str(sod-dob),'days, 0:00:00','')
            tracker.add(str(ds.PatientID))
            PatientList.append(patientDetails)

    return PatientList
Exemplo n.º 5
0
 def test_trait_names(self):
     """Test Dataset.trait_names contains element keywords"""
     test_file = get_testdata_files('CT_small.dcm')[0]
     ds = read_file(test_file, force=True)
     names = ds.trait_names()
     assert 'PatientName' in names
     assert 'save_as' in names
     assert 'PixelData' in names
Exemplo n.º 6
0
 def test_trait_names(self):
     """Test Dataset.trait_names contains element keywords"""
     test_file = os.path.join(DATA_ROOT, 'test_files', 'CT_small.dcm')
     ds = read_file(test_file, force=True)
     names = ds.trait_names()
     assert 'PatientName' in names
     assert 'save_as' in names
     assert 'PixelData' in names
Exemplo n.º 7
0
def read_file(*args, **kwargs):
    global read_file
    from pydicom.dicomio import read_file
    import warnings
    msg = ("The read_file function has moved to pydicom.dicomio. "
           "Please use 'from pydicom import dicomio; dicomio.read_file(...)'")
    warnings.warn(msg, DeprecationWarning)
    return read_file(*args, **kwargs)
Exemplo n.º 8
0
    def getTagObject(self, index):
        """Get the object storing tag information from Dicom file at the given index."""
        if index not in self.tagcache:
            dcm = dicomio.read_file(self.filenames[index],
                                    stop_before_pixels=True)
            self.tagcache[index] = dcm

        return self.tagcache[index]
Exemplo n.º 9
0
def read_file(*args, **kwargs):
    global read_file
    from pydicom.dicomio import read_file
    import warnings
    msg = ("The read_file function has moved to pydicom.dicomio. "
           "Please use 'from pydicom import dicomio; dicomio.read_file(...)'")
    warnings.warn(msg, DeprecationWarning)
    return read_file(*args, **kwargs)
Exemplo n.º 10
0
def load_dicom_file(filename, queue):
    """Load the Dicom file `filename` and put an abbreviated tag->value map onto `queue`."""
    try:
        dcm = dicomio.read_file(filename, stop_before_pixels=True)
        tags = {t: dcm.get(t) for t in LOAD_TAGS if t in dcm}
        queue.put((filename, tags))
    except errors.InvalidDicomError:
        pass
Exemplo n.º 11
0
def extractSeriesDetails(inputImageFile):
    """Reads and extracts Patient's Basic Info from a DICOM file.
    """
    seriesList = []
    dicomfile = inputImageFile
    tracker = set()

    for i, dfile in enumerate(dicomfile):

        seriesDetails = {}
        ds = dicomio.read_file(dfile)
        trackerID = str(ds.SeriesInstanceUID)
        if trackerID in tracker:
            ''
        else:
            seriesDetails["SeriesID"]=ds.SeriesInstanceUID
            seriesDetails["SeriesDescription"]=ds.SeriesDescription
            if ds[0x00080060]:
                seriesDetails["Modality"]=ds.Modality
            else:
                seriesDetails["Modality"]=''

            if ds[0x00200010]:
                seriesDetails["StudyID"]=ds.StudyID

            else:
                seriesDetails["StudyID"]=''

         #   if ds[0x00181030]:
         #      seriesDetails["ProtocolName"]=ds.ProtocolName
       #     else:
         #      seriesDetails["ProtocolName"]=''

        #    if ds[0x00540500]:
        #        seriesDetails["SliceProgressionDirection"]=ds.SliceProgressionDirection
         #   else:
         #       seriesDetails["SliceProgressionDirection"]=''

         #   if ds[0x00280010]:
          #      seriesDetails["Rows"]=ds.Rows
         #   else:
         #       seriesDetails["Rows"]=''

          #  if ds[0x00280011]:
          #      seriesDetails["Columns"]=ds.Columns
         #   else:
           #     seriesDetails["Columns"]=''


            seriesDetails["PatientID"]=ds.PatientID


            tracker.add(str(ds.SeriesInstanceUID))


            seriesList.append(seriesDetails)

    return seriesList
Exemplo n.º 12
0
def loadDicomFiles(filenames, queue):
    """Load the Dicom files `filenames' and put an abbreviated tag->value map for each onto `queue'."""
    for filename in filenames:
        try:
            dcm = dicomio.read_file(filename, stop_before_pixels=True)
            tags = {t: dcm.get(t) for t in loadTags if t in dcm}
            queue.put((filename, tags))
        except errors.InvalidDicomError:
            pass
Exemplo n.º 13
0
    def testEqualityFileMeta(self):
        """Dataset: equality returns correct value if with metadata"""
        d = read_file(self.test_file)
        e = read_file(self.test_file)
        self.assertTrue(d == e)

        e.is_implicit_VR = not e.is_implicit_VR
        self.assertFalse(d == e)

        e.is_implicit_VR = not e.is_implicit_VR
        self.assertTrue(d == e)
        e.is_little_endian = not e.is_little_endian
        self.assertFalse(d == e)

        e.is_little_endian = not e.is_little_endian
        self.assertTrue(d == e)
        e.filename = 'test_filename.dcm'
        self.assertFalse(d == e)
Exemplo n.º 14
0
    def testEqualityFileMeta(self):
        """Dataset: equality returns correct value if with metadata"""
        d = read_file(self.test_file)
        e = read_file(self.test_file)
        self.assertTrue(d == e)

        e.is_implicit_VR = not e.is_implicit_VR
        self.assertFalse(d == e)

        e.is_implicit_VR = not e.is_implicit_VR
        self.assertTrue(d == e)
        e.is_little_endian = not e.is_little_endian
        self.assertFalse(d == e)

        e.is_little_endian = not e.is_little_endian
        self.assertTrue(d == e)
        e.filename = "test_filename.dcm"
        self.assertFalse(d == e)
Exemplo n.º 15
0
 def testLatin1(self):
     """charset: can read and decode latin_1 file........................"""
     ds = dicomio.read_file(latin1_file)
     ds.decode()
     # Make sure don't get unicode encode error on converting to string
     expected = u'Buc^J\xe9r\xf4me'
     got = ds.PatientName
     self.assertEqual(expected, got,
                      "Expected %r, got %r" % (expected, got))
Exemplo n.º 16
0
    def test_get_item(self):
        """Test Dataset.get_item"""
        ds = Dataset()
        ds.CommandGroupLength = 120  # 0000,0000
        ds.SOPInstanceUID = '1.2.3.4'  # 0008,0018

        # Test non-deferred read
        assert ds.get_item(0x00000000) == ds[0x00000000]
        assert ds.get_item(0x00000000).value == 120
        assert ds.get_item(0x00080018) == ds[0x00080018]
        assert ds.get_item(0x00080018).value == '1.2.3.4'

        # Test deferred read
        test_file = get_testdata_files('MR_small.dcm')[0]
        ds = read_file(test_file, force=True, defer_size='0.8 kB')
        ds_ref = read_file(test_file, force=True)
        # get_item will follow the deferred read branch
        assert ds.get_item((0x7fe00010)).value == ds_ref.PixelData
Exemplo n.º 17
0
 def testLatin1(self):
     """charset: can read and decode latin_1 file........................"""
     ds = dicomio.read_file(latin1_file)
     ds.decode()
     # Make sure don't get unicode encode error on converting to string
     expected = u'Buc^J\xe9r\xf4me'
     got = ds.PatientName
     self.assertEqual(expected, got,
                      "Expected %r, got %r" % (expected, got))
Exemplo n.º 18
0
    def testRead(self):
        """Unicode: Can read a file with unicode characters in name..."""
        uni_name = u'test°'

        # verify first that we could encode file name in this environment
        try:
            _ = uni_name.encode(sys.getfilesystemencoding())
        except UnicodeEncodeError:
            print("SKIP: Environment doesn't support unicode filenames")
            return

        try:
            dicomio.read_file(uni_name)
        except UnicodeEncodeError:
            self.fail("UnicodeEncodeError generated for unicode name")
        # ignore file doesn't exist error
        except IOError:
            pass
Exemplo n.º 19
0
 def testEncodingWithSpecificTags(self):
     """Encoding is correctly applied even if  Specific Character Set
     is not in specific tags..."""
     ds = dicomio.read_file(jp_file, specific_tags=['PatientName'])
     ds.decode()
     self.assertEqual(1, len(ds))
     expected = ('Yamada^Tarou='
                 '\033$B;3ED\033(B^\033$BB@O:\033(B='
                 '\033$B$d$^$@\033(B^\033$B$?$m$&\033(B')
     self.assertEqual(expected, ds.PatientName)
Exemplo n.º 20
0
 def testEncodingWithSpecificTags(self):
     """Encoding is correctly applied even if  Specific Character Set
     is not in specific tags..."""
     ds = dicomio.read_file(jp_file, specific_tags=['PatientName'])
     ds.decode()
     self.assertEqual(1, len(ds))
     expected = ('Yamada^Tarou='
                 '\033$B;3ED\033(B^\033$BB@O:\033(B='
                 '\033$B$d$^$@\033(B^\033$B$?$m$&\033(B')
     self.assertEqual(expected, ds.PatientName)
Exemplo n.º 21
0
 def testNestedCharacterSets(self):
     """charset: can read and decode SQ with different encodings........."""
     ds = dicomio.read_file(sq_encoding_file)
     ds.decode()
     # These datasets inside of the SQ cannot be decoded with default_encoding
     # OR UTF-8 (the parent dataset's encoding). Instead, we make sure that it
     # is decoded using the (0008,0005) tag of the dataset
     expected = u'\uff94\uff8f\uff80\uff9e^\uff80\uff9b\uff73=\u5c71\u7530^\u592a\u90ce=\u3084\u307e\u3060^\u305f\u308d\u3046'
     got = ds[0x32, 0x1064][0].PatientName
     self.assertEqual(expected, got,
                      "Expected %r, got %r" % (expected, got))
Exemplo n.º 22
0
    def test_set_convert_private_elem_from_raw(self):
        """Test Dataset.__setitem__ with a raw private element"""
        test_file = get_testdata_files('CT_small.dcm')[0]
        ds = read_file(test_file, force=True)
        # 'tag VR length value value_tell is_implicit_VR is_little_endian'
        elem = RawDataElement((0x0043, 0x1029), 'OB', 2, b'\x00\x01', 0, True,
                              True)
        ds.__setitem__((0x0043, 0x1029), elem)

        assert ds[(0x0043, 0x1029)].value == b'\x00\x01'
        assert type(ds[(0x0043, 0x1029)]) == DataElement
Exemplo n.º 23
0
    def __init__(self, dataset, memmap_pixel_array=False):
        """Initialize DicomParser from a pydicom Dataset or DICOM file.

        Parameters
        ----------
        dataset : pydicom Dataset or filename
            pydicom dataset object or DICOM file location
        memmap_pixel_array : bool, optional
            Enable pixel array access via memory mapping, by default False

        Raises
        ------
        AttributeError
            Raised if SOPClassUID is not present in the pydicom Dataset
        AttributeError
            Raised if the DICOM file or pydicom Dataset cannot be read
        """
        self.memmap_pixel_array = memmap_pixel_array
        if isinstance(dataset, Dataset):
            self.ds = dataset
        elif isinstance(dataset, (string_types, BytesIO)):
            try:
                with open(dataset, "rb") as fp:
                    self.ds = read_file(fp,
                                        defer_size=100,
                                        force=True,
                                        stop_before_pixels=memmap_pixel_array)
                    if memmap_pixel_array:
                        self.offset = fp.tell() + 8
            except Exception:
                # Raise the error for the calling method to handle
                raise
            else:
                # Sometimes DICOM files may not have headers,
                # but they should always have a SOPClassUID
                # to declare what type of file it is.
                # If the file doesn't have a SOPClassUID,
                # then it probably isn't DICOM.
                if "SOPClassUID" not in self.ds:
                    raise AttributeError
        else:
            raise AttributeError
        # Remove the PixelData attribute if it is not set.
        # i.e. RTStruct does not contain PixelData and its presence can confuse
        # the parser
        if "PixelData" in self.ds and self.ds.PixelData is None:
            delattr(self.ds, 'PixelData')
        if memmap_pixel_array:
            self.filename = dataset
            self.pixel_array = self.get_pixel_array
        else:
            if "PixelData" in self.ds:
                self.pixel_array = self.ds.pixel_array
Exemplo n.º 24
0
    def getPixelData(self, index):
        """Get the pixel data array for file at position `index` in self.filenames, or None if no pixel data."""
        if index not in self.imgcache:
            try:
                dcm = dicomio.read_file(self.filenames[index])
                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  # exceptions indicate that the pixel data doesn't exist or isn't readable so ignore

            self.imgcache[index] = img

        return self.imgcache[index]
Exemplo n.º 25
0
    def getPixelData(self, index):
        '''Get the pixel data Numpy array for file at position `index` in self.filenames, or None if there is no pixel data.'''
        if index not in self.imgcache:
            img = None
            try:
                dcm = dicomio.read_file(self.filenames[index])
                rslope = float(dcm.get('RescaleSlope', 1) or 1)
                rinter = float(dcm.get('RescaleIntercept', 0) or 0)
                img = dcm.pixel_array * rslope + rinter
            except Exception:
                pass  # exceptions indicate that the pixel data doesn't exist or isn't readable so ignore

            self.imgcache[index] = img

        return self.imgcache[index]
Exemplo n.º 26
0
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())
Exemplo n.º 27
0
def _load_dicom_files(filenames: str, queue):
    """Для DICOM-файлов из списка filenames загружаем минимальный набор тегов и помещаем в очередь."""
    for filename in filenames:
        try:
            dcm = dicomio.read_file(filename, specific_tags=REQUIRED_TAGS)
            tags = {
                t: dcm.get(t) if t in dcm else DEFAULT_TAG_VAL
                for t in REQUIRED_TAGS
            }
            queue.put((filename, tags))
        except errors.InvalidDicomError:
            pass
        except AttributeError:
            pass
        except:
            pass
Exemplo n.º 28
0
    def getPixelData(self, index):
        '''Get the pixel data Numpy array for file at position `index` in self.filenames, or None if there is no pixel data.'''
        if index not in self.imgcache:
            img = None
            try:
                dcm = dicomio.read_file(self.filenames[index])
                if dcm.pixel_array is not None:
                    rslope = float(dcm.get('RescaleSlope', 1))
                    rinter = float(dcm.get('RescaleIntercept', 0))
                    img = dcm.pixel_array * rslope + rinter
            except Exception:
                pass

            self.imgcache[index] = img

        return self.imgcache[index]
Exemplo n.º 29
0
def anonymize_folder(folder, new_patient_name="Anonymous", verbose=True):
    """
        Anonymizes all dicom files inside a given folder. By default,
        the patient name attribute is replaced by "Anonymous" but an
        alternative name can be provided as an argument to the function.

        NOTE: Assumes all files in the folder belong to the same patient.

        Currently, the following DICOM fields are anonymised:
        RTPlanTime, ReviewTime, StudyTime, RTPlanDate, ReviewDate, StudyDate,
        PatientBirthDate, PatientName, PatientID, StudyID, ReviewerName.
    """

    files = match_dicom(folder)
    times = ["RTPlanTime", "ReviewTime", "StudyTime"]
    dates = ["RTPlanDate", "ReviewDate", "StudyDate", "PatientBirthDate"]

    # Not guaranteed to be unique, but they're not UIDs so it shouldn't matter.
    new_patientID = "ANON" + str(random.randint(0, 1000000))
    new_studyID = "ANON" + str(random.randint(0, 1000000))

    for dicomfile in files:
        try:
            df = dicom.read_file(dicomfile)
            if verbose:
                print "Anonymizing %s" % dicomfile

            if "PatientName" in df:
                df.PatientName = new_patient_name
            if "PatientID" in df:
                df.PatientID = new_patientID
            if "StudyID" in df:
                df.StudyID = new_studyID
            if "ReviewerName" in df:
                df.ReviewerName = "ANON"

            for date in dates:
                if date in df:
                    setattr(df, date, "19000101")

            for time in times:
                if time in df:
                    setattr(df, time, "111111")

            df.save_as(dicomfile)
        except dicom.filereader.InvalidDicomError:
            pass
Exemplo n.º 30
0
def anonymize_folder(folder, new_patient_name="Anonymous", verbose=True):
    """
        Anonymizes all dicom files inside a given folder. By default,
        the patient name attribute is replaced by "Anonymous" but an
        alternative name can be provided as an argument to the function.

        NOTE: Assumes all files in the folder belong to the same patient.

        Currently, the following DICOM fields are anonymised:
        RTPlanTime, ReviewTime, StudyTime, RTPlanDate, ReviewDate, StudyDate,
        PatientBirthDate, PatientName, PatientID, StudyID, ReviewerName.
    """

    files = match_dicom(folder)
    times = ["RTPlanTime", "ReviewTime", "StudyTime"]
    dates = ["RTPlanDate", "ReviewDate", "StudyDate", "PatientBirthDate"]

    # Not guaranteed to be unique, but they're not UIDs so it shouldn't matter.
    new_patientID = "ANON" + str(random.randint(0, 1000000))
    new_studyID = "ANON" + str(random.randint(0, 1000000))

    for dicomfile in files:
        try:
            df = dicom.read_file(dicomfile)
            if verbose:
                print "Anonymizing %s" % dicomfile

            if "PatientName" in df:
                df.PatientName = new_patient_name
            if "PatientID" in df:
                df.PatientID = new_patientID
            if "StudyID" in df:
                df.StudyID = new_studyID
            if "ReviewerName" in df:
                df.ReviewerName = "ANON"

            for date in dates:
                if date in df:
                    setattr(df, date, "19000101")

            for time in times:
                if time in df:
                    setattr(df, time, "111111")

            df.save_as(dicomfile)
        except dicom.filereader.InvalidDicomError:
            pass
Exemplo n.º 31
0
def _imread_dcm(filename):
    """Open DICOM image with pydicom and return a NumPy array"""
    try:
        # pydicom 1.0
        from pydicom import dicomio
    except ImportError:
        # pydicom 0.9
        import dicom as dicomio
    dcm = dicomio.read_file(filename, force=True)
    # **********************************************************************
    # The following is necessary until pydicom numpy support is improved:
    # (after that, a simple: 'arr = dcm.PixelArray' will work the same)
    format_str = "%sint%s" % (
        ("u", "")[dcm.PixelRepresentation], dcm.BitsAllocated)
    try:
        dtype = np.dtype(format_str)
    except TypeError:
        raise TypeError("Data type not understood by NumPy: "
                        "PixelRepresentation=%d, BitsAllocated=%d" %
                        (dcm.PixelRepresentation, dcm.BitsAllocated))
    arr = np.fromstring(dcm.PixelData, dtype)
    try:
        # pydicom 0.9.3:
        dcm_is_little_endian = dcm.isLittleEndian
    except AttributeError:
        # pydicom 0.9.4:
        dcm_is_little_endian = dcm.is_little_endian
    if dcm_is_little_endian != (sys.byteorder == "little"):
        arr.byteswap(True)
    if hasattr(dcm, "NumberofFrames") and dcm.NumberofFrames > 1:
        if dcm.SamplesperPixel > 1:
            arr = arr.reshape(dcm.SamplesperPixel, dcm.NumberofFrames,
                              dcm.Rows, dcm.Columns)
        else:
            arr = arr.reshape(dcm.NumberofFrames, dcm.Rows, dcm.Columns)
    else:
        if dcm.SamplesperPixel > 1:
            if dcm.BitsAllocated == 8:
                arr = arr.reshape(dcm.SamplesperPixel, dcm.Rows, dcm.Columns)
            else:
                raise NotImplementedError(
                    "This code only handles "
                    "SamplesPerPixel > 1 if Bits Allocated = 8")
        else:
            arr = arr.reshape(dcm.Rows, dcm.Columns)
    # **********************************************************************
    return arr
Exemplo n.º 32
0
def get_tag(dicomPath1, dicomPath2):
    dcm = pydicom.dcmread(dicomPath1)  # 选择一个普通的非压缩dcm文件作为转换模板
    image = sitk.ReadImage(dicomPath2)
    image_array = sitk.GetArrayFromImage(image)
    np_array = np.int16(image_array)
    image_array = np.squeeze(np_array)  # 读取有压缩分段的dcm图像数据
    dataset = pydicom.dcmread(dicomPath2)  # 用来修改Tag,图像读写相关的tag都要改
    dcm.data_element('PixelSpacing').value = dataset.data_element(
        'PixelSpacing').value
    dcm.data_element('RescaleIntercept').value = dataset.data_element(
        'RescaleIntercept').value
    dcm.data_element('RescaleSlope').value = dataset.data_element(
        'RescaleSlope').value
    dcm.PixelData = image_array.tobytes()
    dcm.save_as(dicomPath2)
    dcm = dicomio.read_file(dicomPath2)
    return dcm.StudyDescription
Exemplo n.º 33
0
def _imread_dcm(filename):
    """Open DICOM image with pydicom and return a NumPy array"""
    try:
        # pydicom 1.0
        from pydicom import dicomio
    except ImportError:
        # pydicom 0.9
        import dicom as dicomio
    dcm = dicomio.read_file(filename, force=True)
    # **********************************************************************
    # The following is necessary until pydicom numpy support is improved:
    # (after that, a simple: 'arr = dcm.PixelArray' will work the same)
    format_str = '%sint%s' % (('u', '')[dcm.PixelRepresentation],
                              dcm.BitsAllocated)
    try:
        dtype = np.dtype(format_str)
    except TypeError:
        raise TypeError("Data type not understood by NumPy: "
                        "PixelRepresentation=%d, BitsAllocated=%d" % (
                        dcm.PixelRepresentation, dcm.BitsAllocated))
    arr = np.fromstring(dcm.PixelData, dtype)
    try:
        # pydicom 0.9.3:
        dcm_is_little_endian = dcm.isLittleEndian
    except AttributeError:
        # pydicom 0.9.4:
        dcm_is_little_endian = dcm.is_little_endian
    if dcm_is_little_endian != (sys.byteorder == 'little'):
        arr.byteswap(True)
    if hasattr(dcm, 'NumberofFrames') and dcm.NumberofFrames > 1:
        if dcm.SamplesperPixel > 1:
            arr = arr.reshape(dcm.SamplesperPixel, dcm.NumberofFrames,
                              dcm.Rows, dcm.Columns)
        else:
            arr = arr.reshape(dcm.NumberofFrames, dcm.Rows, dcm.Columns)
    else:
        if dcm.SamplesperPixel > 1:
            if dcm.BitsAllocated == 8:
                arr = arr.reshape(dcm.SamplesperPixel, dcm.Rows, dcm.Columns)
            else:
                raise NotImplementedError("This code only handles "
                            "SamplesPerPixel > 1 if Bits Allocated = 8")
        else:
            arr = arr.reshape(dcm.Rows, dcm.Columns)
    # **********************************************************************
    return arr
Exemplo n.º 34
0
def build_dcm_dict(dcmpath, fn_dict, image_dict_pkl="image_dict.pkl"):
    slice_location = []
    trigger_time = []
    image_dict = {}
    hash_value = hashlib.sha1(dcmpath).hexdigest()
    #count = 0
    for dirname, subdirlist, filelist in os.walk(dcmpath):
        for filen in  filelist:
            filePath = os.path.join(dirname,filen)    
            #print(filePath)
            #print(dirname, subdirlist, filelist)
            #print(filePath)
            #print(f.SliceLocation)
            try:
                f = dicomio.read_file(filePath, stop_before_pixels=True)
            except Exception as e: 
               print(str(e))
               print("error: {0}".format(filen))
               continue
            
            #dictionary of images
            if (f.TriggerTime not in image_dict.keys()):
                image_dict[f.TriggerTime] = {}
            if (f.SliceLocation not in image_dict[f.TriggerTime].keys()):
                image_dict[f.TriggerTime][f.SliceLocation] = {}
            
            for fn_key in fn_dict.keys():
                if( fn_key not in image_dict[f.TriggerTime][f.SliceLocation].keys()):
                        image_dict[f.TriggerTime][f.SliceLocation][fn_key] = {}
                #print(fn_key, filen, fn_dict[fn_key])
                if (fnmatch.fnmatch(filen, fn_dict[fn_key])):
                    #print('did i get here')
                    if (f.SOPInstanceUID not in image_dict[f.TriggerTime][f.SliceLocation][fn_key].keys()):
                        image_dict[f.TriggerTime][f.SliceLocation][fn_key][f.SOPInstanceUID] = [filePath]
                        #print(image_dict[fn_key])
            if (f.TriggerTime not in trigger_time):
                trigger_time.append(f.TriggerTime)
            if (f.SliceLocation not in slice_location):
                slice_location.append(f.SliceLocation)
    print("writing {0} to current working directory".format(image_dict_pkl))
    with open(os.path.join(os.getcwd(), image_dict_pkl), "wb") as pkl_f:
        pickle.dump(hash_value, pkl_f, -1)
        pickle.dump(image_dict, pkl_f, -1)
    return image_dict
Exemplo n.º 35
0
def convert_dcm_to_csv(id_label_map, input_filename, output_filename):
    print("Start to convert dcm: {} to csv: {}".format(input_filename,
                                                       output_filename))

    ds = dicomio.read_file(input_filename)
    image_ndarray = ds.pixel_array
    label = id_label_map[ds.PatientID]
    csv_content = "{},".format(label)

    # Example: 512 * 512
    for i in image_ndarray:
        for j in i:
            csv_content += "{},".format(j)
    csv_content = csv_content[:-1] + "\n"

    with open(output_filename, "w") as f:
        f.write(csv_content)

    print("Successfully convert dcm: {} to csv: {}".format(
        input_filename, output_filename))
def convert_dcm_to_csv(id_label_map, input_filename, output_filename):
  print("Start to convert dcm: {} to csv: {}".format(input_filename,
                                                     output_filename))

  ds = dicomio.read_file(input_filename)
  image_ndarray = ds.pixel_array
  label = id_label_map[ds.PatientID]
  csv_content = "{},".format(label)

  # Example: 512 * 512
  for i in image_ndarray:
    for j in i:
      csv_content += "{},".format(j)
  csv_content = csv_content[:-1] + "\n"

  with open(output_filename, "w") as f:
    f.write(csv_content)

  print("Successfully convert dcm: {} to csv: {}".format(input_filename,
                                                         output_filename))
Exemplo n.º 37
0
    def __init__(self, dataset):

        if isinstance(dataset, Dataset):
            self.ds = dataset
        elif isinstance(dataset, (string_types, BytesIO)):
            try:
                self.ds = \
                    read_file(dataset, defer_size=100, force=True)
            except:
                # Raise the error for the calling method to handle
                raise
            else:
                # Sometimes DICOM files may not have headers,
                # but they should always have a SOPClassUID
                # to declare what type of file it is.
                # If the file doesn't have a SOPClassUID,
                # then it probably isn't DICOM.
                if not "SOPClassUID" in self.ds:
                    raise AttributeError
        else:
            raise AttributeError
Exemplo n.º 38
0
    def __init__(self, dataset):

        if isinstance(dataset, Dataset):
            self.ds = dataset
        elif isinstance(dataset, string_types):
            try:
                self.ds = \
                    read_file(dataset, defer_size=100, force=True)
            except:
                # Raise the error for the calling method to handle
                raise
            else:
                # Sometimes DICOM files may not have headers,
                # but they should always have a SOPClassUID
                # to declare what type of file it is.
                # If the file doesn't have a SOPClassUID,
                # then it probably isn't DICOM.
                if not "SOPClassUID" in self.ds:
                    raise AttributeError
        else:
            raise AttributeError
Exemplo n.º 39
0
def loadDicomZip(filename, statusfunc=lambda s, c, n: None):
    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 = StringIO(z.read(n))
            try:
                dcm = dicomio.read_file(s)
            except:
                pass  # ignore files which aren't Dicom files
            else:
                seriesid = dcm.get('SeriesInstanceUID', '???')

                if seriesid not in series:
                    series[seriesid] = DicomSeries(seriesid, nfilename)

                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())
Exemplo n.º 40
0
def read_file(*args, **kwargs):
    global read_file
    from pydicom.dicomio import read_file
    return read_file(*args, **kwargs)
Exemplo n.º 41
0
def create_image_volume(image_dict, mri_2_cfd_map, image_type, return_coord=True):
    trigger_t = mri_2_cfd_map[0]
    slice_location = image_dict[trigger_t].keys()
    dcm_files = []    
    for loc in slice_location:
      for image_id in image_dict[trigger_t][loc][image_type].keys():
        dcm_files.append(image_dict[trigger_t][loc][image_type][image_id][0])

    path_loc = zip(dcm_files, slice_location)
    path_loc.sort(key=lambda x: x[1])
    dcm_files, slice_location = zip(*path_loc)
    #print(slice_location)
    
    # get reference image
    #print(len(dcm_files), dcm_files)
    ref_image = dicomio.read_file(dcm_files[0])
    # load dimensions based on the number of rows columns and slices
    const_pixel_dims = (int(ref_image.Rows), int(ref_image.Columns), len(dcm_files))
    
    #check it whether image has been interpolated
    if (hasattr(ref_image, 'SpacingBetweenSlices')):
      if(ref_image.SpacingBetweenSlices < ref_image.SliceThickness):
        z_spacing = float(ref_image.SpacingBetweenSlices)
      else:
        z_spacing = float(ref_image.SliceThickness)
    else:
      z_spacing = float(ref_image.SliceThickness)


    # the array is sized based on 'const_pixel_dims
    
    array_dicom = np.zeros(const_pixel_dims, dtype=np.float64) #ref_image.pixel_array.dtype)
    print(array_dicom.shape)
    #loop through all the DICOM FILES
    for filenamedcm in dcm_files:
      #read the file
      ds = dicomio.read_file(filenamedcm)
      #store the raw image data
      array_dicom[:, :, dcm_files.index(filenamedcm)] = (
          np.asarray(ds.pixel_array, dtype=np.float64) * (
          np.float64(ds.RescaleSlope)) + np.float64(ds.RescaleIntercept))
    
    #testindx = np.where(array_dicom !=0)
    #minx = np.min(testindx[0])
    #miny = np.min(testindx[1])
    #minz = np.min(testindx[2])
    #maxx = np.max(testindx[0])
    #maxy = np.max(testindx[1])
    #maxz = np.max(testindx[2])
    
    if (return_coord == True):
      # load spacing values in mm
      const_pixel_spacing = (float(ref_image.PixelSpacing[0]), 
                             float(ref_image.PixelSpacing[1]), z_spacing)
      x = np.arange(const_pixel_spacing[0]/2.0, (const_pixel_dims[0]+1)*const_pixel_spacing[0]-1.0,
                    const_pixel_spacing[0])
      y = np.arange(const_pixel_spacing[1]/2.0, (const_pixel_dims[1]+1)*const_pixel_spacing[1]-1.0,
                    const_pixel_spacing[1])
      z = np.arange(const_pixel_spacing[2]/2.0, (const_pixel_dims[2]+1)*const_pixel_spacing[2]-1.0,
                    const_pixel_spacing[2])
      return array_dicom, x,y,z
    else:
      return array_dicom
Exemplo n.º 42
0
dicom_test = np.testing.dec.skipif(not have_dicom, "could not import pydicom")

from .. import dicomwrappers as didw
from .. import dicomreaders as didr
from ...volumeutils import endian_codes

from unittest import TestCase
from nose.tools import assert_true, assert_false, assert_equal, assert_not_equal, assert_raises

from numpy.testing import assert_array_equal, assert_array_almost_equal

IO_DATA_PATH = pjoin(dirname(__file__), "data")
DATA_FILE = pjoin(IO_DATA_PATH, "siemens_dwi_1000.dcm.gz")
DATA_FILE_PHILIPS = pjoin(IO_DATA_PATH, "philips_mprage.dcm.gz")
if have_dicom:
    DATA = read_file(gzip.open(DATA_FILE))
    DATA_PHILIPS = read_file(gzip.open(DATA_FILE_PHILIPS))
else:
    DATA = None
    DATA_PHILIPS = None
DATA_FILE_B0 = pjoin(IO_DATA_PATH, "siemens_dwi_0.dcm.gz")
DATA_FILE_SLC_NORM = pjoin(IO_DATA_PATH, "csa_slice_norm.dcm")
DATA_FILE_DEC_RSCL = pjoin(IO_DATA_PATH, "decimal_rescale.dcm")
DATA_FILE_4D = pjoin(IO_DATA_PATH, "4d_multiframe_test.dcm")

# This affine from our converted image was shown to match our image spatially
# with an image from SPM DICOM conversion. We checked the matching with SPM
# check reg.  We have flipped the first and second rows to allow for rows, cols
# transpose in current return compared to original case.
EXPECTED_AFFINE = np.array(  # do this for philips?
    [
Exemplo n.º 43
0
Arquivo: main.py Projeto: Olwn/dicomer
def de_sensitive(path, write_to):
    dc = dicomio.read_file(path, force=True)
    for tag in info_deleted:
        if tag in dc:
            del dc[dc.data_element(tag).tag]
    dicomio.write_file(write_to, dc)
Exemplo n.º 44
0
from .. import dicomwrappers as didw
from .. import dicomreaders as didr
from ...volumeutils import endian_codes

from unittest import TestCase
from nose.tools import (assert_true, assert_false, assert_equal,
                        assert_not_equal, assert_raises)

from numpy.testing import assert_array_equal, assert_array_almost_equal

IO_DATA_PATH = pjoin(dirname(__file__), 'data')
DATA_FILE = pjoin(IO_DATA_PATH, 'siemens_dwi_1000.dcm.gz')
DATA_FILE_PHILIPS = pjoin(IO_DATA_PATH, 'philips_mprage.dcm.gz')
if have_dicom:
    DATA = read_file(gzip.open(DATA_FILE))
    DATA_PHILIPS = read_file(gzip.open(DATA_FILE_PHILIPS))
else:
    DATA = None
    DATA_PHILIPS = None
DATA_FILE_B0 = pjoin(IO_DATA_PATH, 'siemens_dwi_0.dcm.gz')
DATA_FILE_SLC_NORM = pjoin(IO_DATA_PATH, 'csa_slice_norm.dcm')
DATA_FILE_DEC_RSCL = pjoin(IO_DATA_PATH, 'decimal_rescale.dcm')
DATA_FILE_4D = pjoin(IO_DATA_PATH, '4d_multiframe_test.dcm')

# This affine from our converted image was shown to match our image spatially
# with an image from SPM DICOM conversion. We checked the matching with SPM
# check reg.  We have flipped the first and second rows to allow for rows, cols
# transpose in current return compared to original case.
EXPECTED_AFFINE = np.array(  # do this for philips?
    [[-1.796875, 0, 0, 115], [0, -1.79684984, -0.01570896, 135.028779],
Exemplo n.º 45
0
def transform2(iminfo1):
  cos = iminfo1.ImageOrientationPatient
  cosines = [np.float64(val) for val in cos]
  ipp = iminfo1.ImagePositionPatient

  normal = [0., 0., 0.]
  normal[0] = cosines[1]*cosines[5] - cosines[2]*cosines[4]
  normal[1] = cosines[2]*cosines[3] - cosines[0]*cosines[5]
  normal[2] = cosines[0]*cosines[4] - cosines[1]*cosines[3]
  #print(normal)
  dist = 0.0
  for i in range(3):
    dist += normal[i]*np.float64(ipp[i])

  #print(dist)
  return dist

if __name__ == '__main__':
  dcm_path = "/home/ksansom/caseFiles/mri/images/0.4/102"
  #dcm_path = "/Users/sansomk/caseFiles/mri/E431791260_merge/0.4/102"
  ds1 = dicomio.read_file(os.path.join(dcm_path, 'E431791260S201I001.dcm'))
  ds2 = dicomio.read_file(os.path.join(dcm_path, 'E431791260S201I002.dcm'))

  M, Rot = getTransformMatrix(ds1, ds2)
  print(M)
  print(Rot)
  dist1 = transform2(ds1)
  dist2 = transform2(ds2)
  print(dist2-dist1)
Exemplo n.º 46
0
 def testExplicitISO2022_IR6(self):
     """charset: can decode file with multi-valued data elements........."""
     ds = dicomio.read_file(explicit_ir6_file)
     ds.decode()
Exemplo n.º 47
0
from pydicom import dicomio

directory = "/media/carlos/CE2CDDEF2CDDD317/concursos/cancer/stage 1 samples/"
patient = "0a0c32c9e08cc2ea76a71649de56be6d"
ds = dicomio.read_file(directory + patient +
                       "/0a67f9edb4915467ac16a565955898d3.dcm")  # plan dataset
print "name:", ds.PatientName
print "dir setup:", ds.dir(
    "setup")  # get a list of tags with "setup" somewhere in the name
print ds
#print ds.PatientSetupSequence[0]
#ds.PatientSetupSequence[0].PatientPosition = "HFP"
#ds.save_as("rtplan2.dcm")
Exemplo n.º 48
0
('?' lines from difflib removed - no use here)
"""

#import sys
from pydicom import dicomio
import difflib

# only used as a script
#if len(sys.argv) != 3:
#    print(usage)
#    sys.exit()

file1 = "/Users/sansomk/caseFiles/mri/E431791260_FlowVol_01/flow/FlowX_001.dcm"
file2 = "/Users/sansomk/caseFiles/mri/E431791260_FlowVol_01/flow/FlowZ_001.dcm"

datasets = (dicomio.read_file(file1, force=True),
            dicomio.read_file(file2, force=True))

# diflib compare functions require a list of lines, each terminated with newline character
# massage the string representation of each dicom dataset into this form:
rep = []
for dataset in datasets:
    lines = str(dataset).split("\n")
    lines = [line + "\n" for line in lines]  # add the newline to end
    rep.append(lines)


diff = difflib.Differ()
for line in diff.compare(rep[0], rep[1]):
    if line[0] != "?":
        print(line)
Exemplo n.º 49
0
 def testStandardFile(self):
     """charset: can read and decode standard file without special char.."""
     ds = dicomio.read_file(normal_file)
     ds.decode()
Exemplo n.º 50
0
 def testMultiPN(self):
     """charset: can decode file with multi-valued data elements........."""
     ds = dicomio.read_file(multiPN_file)
     ds.decode()
Exemplo n.º 51
0
################################################################################
if __name__ == '__main__':
    #dcm_path = "/home/sansomk/caseFiles/mri/images/E431791260_Merge/0.4/102"
    #dcm_path = "/home/sansomk/caseFiles/mri/images/E431791260_FlowVol_01/mag"
    #dcm_path = "/home/ksansom/caseFiles/mri/images/0.4/102/"
    dcm_path = "/Users/sansomk/caseFiles/mri/E431791260_merge/0.4/102"
    dcm_files = []
    slice_location = []
    acq_N = []
    trig_count = 0
    for dirname, subdirlist, filelist in os.walk(dcm_path):
      for filen in filelist:
        filePath = os.path.join(dirname, filen)
        try:          
          #print(filePath)
          f = dicomio.read_file(filePath, stop_before_pixels=True)
        except Exception as e: 
          print(str(e))
          print("error: {0}".format(filen))
        
        if (hasattr(f, "TriggerTime")):
          if (f.TriggerTime < 1.0 and filePath not in dcm_files):
            dcm_files.append(filePath)
            slice_location.append(f.SliceLocation)
            acq_N.append(f.AcquisitionNumber)
        else:
          trig_count += 1
          dcm_files.append(filePath)
          slice_location.append(f.SliceLocation)
          acq_N.append(f.AcquisitionNumber)
    if (trig_count > 0):