A Multi-platform DICOM Toolbox for Academic Radiologists

The Digital Imaging and Communications in Medicine (DICOM) standard is used to store and transmit medical images. Radiology workstations attached to a picture archiving and communication systems (PACS) are used to display these images for diagnostic purposes.

However, diagnostic workstations are sometimes not optimal for academic research purposes. It is often necessary to anonymize DICOM images for research studies or for publication.

This Jupyter notebook contains code to accomplish several useful tasks with DICOM images.

  1. How do I open and view a DICOM image?
  2. How do I view and edit DICOM data elements?
  3. How do I anonymize a DICOM image?
  4. How do I anonymize a whole folder of DICOM images?
  5. How do I save a DICOM image as some other format (.JPG, .PNG, .TIFF)?
  6. How do I window/level and otherwise optimize a DICOM image?
  7. How do I invert a gray-scale image?
  8. How do I flip an image about its horizontal and vertical axes?
  9. How do I open a color DICOM image?
  10. How do I redact protected health information that is embedded within an image (i.e. US or radionuclide images)?

This toolbox includes several HIPAA-compliant DICOM images for your delectation. We have done our best to replace every bit of the original protected health information (PHI) with fictitious entries, using names and locations of characters from the works of Mark Twain.

Installing pydicom

This notebook assumes that you have already installed Jupyter and scientific Python. If not, we highly recommend the Anaconda Python distribution. The Anaconda distribution makes it easy to conveniently install Python, the Jupyter Notebook, and many other commonly used packages for scientific computing and data science.

While Anaconda contains many wonderful packages for science and mathematics, it does not know how to deal with DICOM images. However, there is a great and free add-on package called pydicom, and located at the Anaconda website.

You can install pydicom on your system very simply via this Jupyter notebook. Simply select the next cell in this notebook and hit shift-Return.

Please note that this only has to be done once.

In [ ]:
!conda install -c conda-forge pydicom=0.9.9 --yes

Having installed pydicom, it is now time to work with some images.

Loading a few useful libraries

First, we will ask Python to import a few useful libraries that will do the heavy lifting for us:

  1. pydicom --- each time we start up our notebook, we need to reload this library. Oddly enough, loading this requires that we type "import dicom", rather than "import pydicom".
  2. matplotlilb --- we will use this rather powerful library to do most of the actual plotting.
  3. numpy --- an amazing library of mathematical routines
  4. scikit-image library --- a number of useful image-processing routines
  5. os --- this module to perform certain operating system functions, such as reading or writing a file
  6. glob --- this module finds all the pathnames matching a specified pattern, which is useful in performing operations on every file found in a given folder
  7. datetime --- this module allows one to manipulate dates and times in both simple and complex ways
In [2]:
# this following line tells Jupyter to display images here in the browser, 
# rather than in separate window.

%matplotlib inline 

# import pydicom library

import dicom

# import matplotlib and numpy

import matplotlib.pyplot as plt 
import matplotlib.image as mpimage
import numpy as np 
In [13]:
# load some handy functions from the scikit-image library

from skimage import exposure
import skimage.morphology as morp
from skimage.filters import rank

# import operating system and glob libraries

import os, glob

# import some useful date functions

from datetime import datetime

1. Reading and viewing a DICOM image

We have included several sample DICOM images in this tutorial. This example uses an image called: "Knee_MR.dcm". We will now show you how to load and view this image using Jupyter.

In [4]:
ds1 = dicom.read_file("Knee_MR.dcm")  # read the DICOM image into memory
In [5]:
# tell matplotlib to display our images as a 6 x 6 inch image, with resolution of 100 dpi
plt.figure(figsize = (6,6), dpi=100) 

# tell matplotlib to display our image, using a gray-scale lookup table.
plt.imshow(ds1.pixel_array, cmap=plt.cm.gray) 
Out[5]:
<matplotlib.image.AxesImage at 0x10f174d68>

Voilà! A coronal MR image is now visible for our delectation.

Now, let's look at the DICOM header to learn a bit more about this patient.

2. Examining data elements in the DICOM image header

The DICOM file format is extremely large and complex. It contains not only the image pixel data, but also a large image header with many DICOM_data_elements. These data elemenets contain patient identifiers and detailed information about the imaging device and how the image was obtained.

Thankfully, most DICOM files that we use will not include every possible data element from the DICOM standard. However, there will be a bunch of them. To see what is lurking under the hood on this image, select the code field below, and hit shift-return. Then, take a moment and scroll through some of the many data fields that were included in this image file.

In [6]:
ds1
Out[6]:
(0008, 0000) Group Length                        UL: 1466
(0008, 0005) Specific Character Set              CS: 'ISO_IR 100'
(0008, 0008) Image Type                          CS: ['ORIGINAL', 'PRIMARY', 'M_SE', 'M', 'SE']
(0008, 0012) Instance Creation Date              DA: '18840101'
(0008, 0013) Instance Creation Time              TM: '133545.040'
(0008, 0014) Instance Creator UID                UI: 1.3.46.670589.11.89.5
(0008, 0016) SOP Class UID                       UI: MR Image Storage
(0008, 0018) SOP Instance UID                    UI: 1.3.46.670589.11.42127.5.0.5000.2015050113333847378
(0008, 0020) Study Date                          DA: '18840101'
(0008, 0021) Series Date                         DA: '18840101'
(0008, 0022) Acquisition Date                    DA: '18840101'
(0008, 0023) Content Date                        DA: '18840101'
(0008, 0030) Study Time                          TM: '131343'
(0008, 0031) Series Time                         TM: '133150.18000'
(0008, 0032) Acquisition Time                    TM: '133224.70'
(0008, 0033) Content Time                        TM: '133224.70'
(0008, 0050) Accession Number                    SH: '87654321'
(0008, 0060) Modality                            CS: 'MR'
(0008, 0064) Conversion Type                     CS: ''
(0008, 0070) Manufacturer                        LO: 'Philips Healthcare'
(0008, 0080) Institution Name                    LO: 'Twain Memorial Hospital'
(0008, 0081) Institution Address                 ST: '10 Main Street, St. Petersburg. MO'
(0008, 0090) Referring Physician's Name          PN: ''
(0008, 0100) Code Value                          SH: ''
(0008, 0102) Coding Scheme Designator            SH: ''
(0008, 0104) Code Meaning                        LO: ''
(0008, 1010) Station Name                        SH: 'PHILIPS-2QVUD'
(0008, 1030) Study Description                   LO: 'MRI KNEE WO CONTRAST RIGHT'
(0008, 1032)  Procedure Code Sequence   1 item(s) ---- 
   (0008, 0000) Group Length                        UL: 74
   (0008, 0100) Code Value                          SH: 'MKNEWOR'
   (0008, 0102) Coding Scheme Designator            SH: 'LOCAL'
   (0008, 0104) Code Meaning                        LO: 'MRI KNEE WO CONTRAST RIGHT'
   (0008, 010b) Context Group Extension Flag        CS: 'N'
   ---------
(0008, 103e) Series Description                  LO: 'COR PD SPAIR RT'
(0008, 1040) Institutional Department Name       LO: 'Radiology'
(0008, 1050) Performing Physician's Name         PN: ''
(0008, 1070) Operators' Name                     PN: ''
(0008, 1080) Admitting Diagnoses Description     LO: ''
(0008, 1090) Manufacturer's Model Name           LO: 'Ingenia'
(0008, 1110)  Referenced Study Sequence   1 item(s) ---- 
   (0008, 0000) Group Length                        UL: 90
   (0008, 1150) Referenced SOP Class UID            UI: Detached Study Management SOP Class
   (0008, 1155) Referenced SOP Instance UID         UI: 1.2.840.113745.101000.1061000.42120.4356.22795275
   ---------
(0008, 1111)  Referenced Performed Procedure Step Sequence   1 item(s) ---- 
   (0008, 0000) Group Length                        UL: 156
   (0008, 0012) Instance Creation Date              DA: '20150501'
   (0008, 0013) Instance Creation Time              TM: '131343.460'
   (0008, 0014) Instance Creator UID                UI: 1.3.46.670589.11.89.5
   (0008, 1150) Referenced SOP Class UID            UI: Modality Performed Procedure Step SOP Class
   (0008, 1155) Referenced SOP Instance UID         UI: 1.3.46.670589.11.42127.5.0.9024.2015050113134346008
   (0020, 0000) Group Length                        UL: 10
   (0020, 0013) Instance Number                     IS: '0'
   (2005, 0000) Private Creator                     UL: 54
   (2005, 0014) Private tag data                    LO: 'Philips MR Imaging DD 005'
   (2005, 1404) Private tag data                    SS: 1
   (2005, 1406) [Unknown]                           SS: 1
   ---------
(0008, 1140)  Referenced Image Sequence   3 item(s) ---- 
   (0008, 0000) Group Length                        UL: 94
   (0008, 1150) Referenced SOP Class UID            UI: MR Image Storage
   (0008, 1155) Referenced SOP Instance UID         UI: 1.3.46.670589.11.42127.5.0.5000.2015050113302087317
   ---------
   (0008, 0000) Group Length                        UL: 94
   (0008, 1150) Referenced SOP Class UID            UI: MR Image Storage
   (0008, 1155) Referenced SOP Instance UID         UI: 1.3.46.670589.11.42127.5.0.5000.2015050113260402282
   ---------
   (0008, 0000) Group Length                        UL: 94
   (0008, 1150) Referenced SOP Class UID            UI: MR Image Storage
   (0008, 1155) Referenced SOP Instance UID         UI: 1.3.46.670589.11.42127.5.0.5000.2015050113260409294
   ---------
(0009, 0000) Private Creator                     UL: 4148
(0009, 0010) Private tag data                    LO: 'GEIIS'
(0009, 1010)  [GE IIS Thumbnail Sequence]   1 item(s) ---- 
   (0028, 0002) Samples per Pixel                   US: 1
   (0028, 0004) Photometric Interpretation          CS: 'MONOCHROME2'
   (0028, 0010) Rows                                US: 128
   (0028, 0011) Columns                             US: 128
   (0028, 0100) Bits Allocated                      US: 16
   (0028, 0101) Bits Stored                         US: 12
   (0028, 0102) High Bit                            US: 11
   (0028, 0103) Pixel Representation                US: 0
   (0029, 0000) Private Creator                     UL: 50
   (0029, 0010) Private tag data                    LO: 'GEIIS'
   (0029, 1010) [Shift Count]                       UL: 0
   (0029, 1012) [Offset]                            UL: 0
   (0029, 1014) [Actual Frame Number]               UL: 1
   (7fd1, 0000) Private Creator                     UL: 26
   (7fd1, 0010) Private tag data                    LO: 'GEIIS'
   (7fd1, 1010) [GE IIS Compression ID]             UL: 26
   (7fe0, 0010) Pixel Data                          OB: Array of 3912 bytes
   ---------
(0010, 0000) Group Length                        UL: 150
(0010, 0010) Patient's Name                      PN: 'Finn, Huckleberry'
(0010, 0020) Patient ID                          LO: '12345678'
(0010, 0030) Patient's Birth Date                DA: '18700101'
(0010, 0040) Patient's Sex                       CS: 'M'
(0010, 1010) Patient's Age                       AS: '14'
(0010, 1030) Patient's Weight                    DS: '120'
(0010, 2000) Medical Alerts                      LO: ''
(0010, 2110) Allergies                           LO: ''
(0010, 2160) Ethnic Group                        SH: ''
(0010, 2180) Occupation                          SH: ''
(0010, 21b0) Additional Patient History          LT: ''
(0010, 21c0) Pregnancy Status                    US: 4
(0010, 4000) Patient Comments                    LT: ''
(0018, 0000) Group Length                        UL: 582
(0018, 0015) Body Part Examined                  CS: ''
(0018, 0020) Scanning Sequence                   CS: 'SE'
(0018, 0021) Sequence Variant                    CS: 'SK'
(0018, 0022) Scan Options                        CS: 'FS'
(0018, 0023) MR Acquisition Type                 CS: '2D'
(0018, 0050) Slice Thickness                     DS: '3'
(0018, 0080) Repetition Time                     DS: '2231.00708007812'
(0018, 0081) Echo Time                           DS: '17'
(0018, 0083) Number of Averages                  DS: '2'
(0018, 0084) Imaging Frequency                   DS: '127.743296'
(0018, 0085) Imaged Nucleus                      SH: '1H'
(0018, 0086) Echo Number(s)                      IS: '1'
(0018, 0087) Magnetic Field Strength             DS: '3'
(0018, 0088) Spacing Between Slices              DS: '3.5'
(0018, 0089) Number of Phase Encoding Steps      IS: '259'
(0018, 0091) Echo Train Length                   IS: '11'
(0018, 0093) Percent Sampling                    DS: '100'
(0018, 0094) Percent Phase Field of View         DS: '87.5'
(0018, 0095) Pixel Bandwidth                     DS: '347'
(0018, 1000) Device Serial Number                LO: '42127'
(0018, 1010) Secondary Capture Device ID         LO: ''
(0018, 1016) Secondary Capture Device Manufactur LO: ''
(0018, 1018) Secondary Capture Device Manufactur LO: ''
(0018, 1019) Secondary Capture Device Software V LO: ''
(0018, 1020) Software Version(s)                 LO: ['5.1.7', '5.1.7.2']
(0018, 1022) Video Image Format Acquired         SH: ''
(0018, 1023) Digital Image Format Acquired       LO: ''
(0018, 1030) Protocol Name                       LO: 'COR PD SPAIR RT SENSE'
(0018, 1081) Low R-R Value                       IS: '0'
(0018, 1082) High R-R Value                      IS: '0'
(0018, 1083) Intervals Acquired                  IS: '0'
(0018, 1084) Intervals Rejected                  IS: '0'
(0018, 1088) Heart Rate                          IS: '0'
(0018, 1100) Reconstruction Diameter             DS: '150'
(0018, 1250) Receive Coil Name                   SH: 'SENSE_KNEE_16_AC'
(0018, 1310) Acquisition Matrix                  US: [0, 288, 259, 0]
(0018, 1312) In-plane Phase Encoding Direction   CS: 'ROW'
(0018, 1314) Flip Angle                          DS: '90'
(0018, 1316) SAR                                 DS: '0.12885656952857'
(0018, 1318) dB/dt                               DS: '91.7316284179687'
(0018, 5100) Patient Position                    CS: 'FFS'
(0018, 9073) Acquisition Duration                FD: 147.24647521972656
(0018, 9087) Diffusion b-value                   FD: 0.0
(0018, 9089) Diffusion Gradient Orientation      FD: [0.0, 0.0, 0.0]
(0020, 0000) Group Length                        UL: 456
(0020, 000d) Study Instance UID                  UI: 1.2.840.113745.101000.1061000.42120.4356.22795275
(0020, 000e) Series Instance UID                 UI: 1.3.46.670589.11.42127.5.0.5000.2015050113315021335
(0020, 0010) Study ID                            SH: '473199223'
(0020, 0011) Series Number                       IS: '801'
(0020, 0012) Acquisition Number                  IS: '8'
(0020, 0013) Instance Number                     IS: '19'
(0020, 0032) Image Position (Patient)            DS: ['-174.38114202721', '-41.175347426091', '56.9054756642145']
(0020, 0037) Image Orientation (Patient)         DS: ['0.97852188348770', '-0.1848892867565', '-0.0911637097597', '-0.0771425366401', '0.08167532086372', '-0.9936690330505']
(0020, 0052) Frame of Reference UID              UI: 1.3.46.670589.11.42127.5.0.8860.2015050113125617007
(0020, 0060) Laterality                          CS: ''
(0020, 0100) Temporal Position Identifier        IS: '1'
(0020, 0105) Number of Temporal Positions        IS: '1'
(0020, 1040) Position Reference Indicator        LO: ''
(0020, 1041) Slice Location                      DS: '3778.47181036314'
(0028, 0000) Group Length                        UL: 148
(0028, 0002) Samples per Pixel                   US: 1
(0028, 0004) Photometric Interpretation          CS: 'MONOCHROME2'
(0028, 0010) Rows                                US: 512
(0028, 0011) Columns                             US: 512
(0028, 0030) Pixel Spacing                       DS: ['0.29296875', '0.29296875']
(0028, 0100) Bits Allocated                      US: 16
(0028, 0101) Bits Stored                         US: 12
(0028, 0102) High Bit                            US: 11
(0028, 0103) Pixel Representation                US: 0
(0028, 1050) Window Center                       DS: '246.33'
(0028, 1051) Window Width                        DS: '428.24'
(0032, 0000) Group Length                        UL: 66
(0032, 1032) Requesting Physician                PN: ''
(0032, 1033) Requesting Service                  LO: ''
(0032, 1060) Requested Procedure Description     LO: 'MRI KNEE WO CONTRAST RIGHT'
(0032, 1070) Requested Contrast Agent            LO: ''
(0032, 4000) Study Comments                      LT: ''
(0038, 0000) Group Length                        UL: 16
(0038, 0050) Special Needs                       LO: ''
(0038, 0500) Patient State                       LO: ''
(0040, 0000) Group Length                        UL: 720
(0040, 0006) Scheduled Performing Physician's Na PN: ''
(0040, 0241) Performed Station AE Title          AE: 'UMMRI3'
(0040, 0242) Performed Station Name              SH: ''
(0040, 0243) Performed Location                  SH: ''
(0040, 0244) Performed Procedure Step Start Date DA: '18840101'
(0040, 0245) Performed Procedure Step Start Time TM: '131343'
(0040, 0250) Performed Procedure Step End Date   DA: '18840101'
(0040, 0251) Performed Procedure Step End Time   TM: '131343'
(0040, 0252) Performed Procedure Step Status     CS: ''
(0040, 0253) Performed Procedure Step ID         SH: '473199223'
(0040, 0254) Performed Procedure Step Descriptio LO: 'MRI KNEE WO CONTRAST RIGHT'
(0040, 0255) Performed Procedure Type Descriptio LO: ''
(0040, 0260)  Performed Protocol Code Sequence   1 item(s) ---- 
   (0008, 0000) Group Length                        UL: 52
   (0008, 0100) Code Value                          SH: 'STUBB'
   (0008, 0102) Coding Scheme Designator            SH: 'STUBB'
   (0008, 0104) Code Meaning                        LO: 'STUBB'
   (0008, 010b) Context Group Extension Flag        CS: 'N'
   ---------
(0040, 0275)  Request Attributes Sequence   1 item(s) ---- 
   (0040, 0000) Group Length                        UL: 166
   (0040, 0007) Scheduled Procedure Step Descriptio LO: 'MRI KNEE WO CONTRAST RIGHT'
   (0040, 0008)  Scheduled Protocol Code Sequence   1 item(s) ---- 
      (0008, 0000) Group Length                        UL: 52
      (0008, 0100) Code Value                          SH: 'STUBB'
      (0008, 0102) Coding Scheme Designator            SH: 'STUBB'
      (0008, 0104) Code Meaning                        LO: 'STUBB'
      (0008, 010b) Context Group Extension Flag        CS: 'N'
      ---------
   (0040, 0009) Scheduled Procedure Step ID         SH: '10530580'
   (0040, 0012) Pre-Medication                      LO: ''
   (0040, 0400) Comments on the Scheduled Procedure LT: ''
   (0040, 1001) Requested Procedure ID              SH: '9123711'
   ---------
(0040, 0280) Comments on the Performed Procedure ST: ''
(0040, 1001) Requested Procedure ID              SH: '87654321'
(0040, 1002) Reason for the Requested Procedure  LO: ''
(0040, 1003) Requested Procedure Priority        SH: ''
(0040, 1004) Patient Transport Arrangements      LO: ''
(0040, 1005) Requested Procedure Location        LO: ''
(0040, 1400) Requested Procedure Comments        LT: ''
(0040, 2001) Reason for the Imaging Service Requ LO: ''
(0040, 2004) Issue Date of Imaging Service Reque DA: '18840101'
(0040, 2005) Issue Time of Imaging Service Reque TM: '131343.406'
(0040, 2009) Order Enterer's Location            SH: ''
(0040, 2010) Order Callback Phone Number         SH: ''
(0040, 2400) Imaging Service Request Comments    LT: ''
(0040, 9096)  Real World Value Mapping Sequence   1 item(s) ---- 
   (0040, 0000) Group Length                        UL: 32
   (0040, 9224) Real World Value Intercept          FD: 0.0
   (0040, 9225) Real World Value Slope              FD: 10.68083028083028
   (2001, 0000) Private Creator                     UL: 66
   (2001, 0010) Private tag data                    LO: 'Philips Imaging DD 001'
   (2001, 10c1) [Nested Object Type Name]           LO: 'LinearRealWorldValueMapping'
   ---------
(0905, 0010) Private Creator                     LO: 'GEIIS'
(0905, 1030) [Assigning Authority For Patient ID LO: '001G01:20060723:020224483:016580'
(2001, 0000) Private Creator                     UL: 1112
(2001, 0010) Private tag data                    LO: 'Philips Imaging DD 001'
(2001, 0011) Private tag data                    LO: 'Philips Imaging DD 002'
(2001, 1001) [Chemical Shift]                    FL: 0.0
(2001, 1002) [Chemical Shift Number MR]          IS: '0'
(2001, 1003) [Diffusion B-Factor]                FL: 0.0
(2001, 1004) [Diffusion Direction]               CS: ''
(2001, 1006) [Image Enhanced]                    CS: 'N'
(2001, 1007) [Image Type ED ES]                  CS: 'U'
(2001, 1008) [Phase Number]                      IS: '1'
(2001, 1009) [Unknown]                           FL: 0.0
(2001, 100a) [Slice Number MR]                   IS: '19'
(2001, 100b) [Slice Orientation]                 CS: 'CORONAL'
(2001, 100c) [Unknown]                           CS: 'N'
(2001, 100e) [Unknown]                           CS: 'N'
(2001, 100f) [Unknown]                           SS: 0
(2001, 1010) [Cardiac Sync]                      CS: 'NO'
(2001, 1011) [Diffusion Echo Time]               FL: 0.0
(2001, 1012) [Dynamic Series]                    CS: 'N'
(2001, 1013) [EPI Factor]                        SL: 1
(2001, 1014) [Number of Echoes]                  SL: 1
(2001, 1015) [Number of Locations]               SS: 1
(2001, 1016) [Number of PC Directions]           SS: 0
(2001, 1017) [Number of Phases MR]               SL: 1
(2001, 1018) [Number of Slices MR]               SL: 30
(2001, 1019) [Partial Matrix Scanned]            CS: 'N'
(2001, 101a) [PC Velocity]                       FL: [0.0, 0.0, 0.0]
(2001, 101b) [Prepulse Delay]                    FL: 0.0
(2001, 101c) [Prepulse Type]                     CS: 'NO'
(2001, 101d) [Reconstruction Number MR]          IS: '1'
(2001, 101e) [Unknown]                           CS: ''
(2001, 101f) [Respiration Sync]                  CS: 'NO'
(2001, 1020) [Scanning Technique Description MR] LO: 'TSE'
(2001, 1021) [SPIR]                              CS: 'Y'
(2001, 1022) [Water Fat Shift]                   FL: 1.2508628368377686
(2001, 1023) [Flip Angle Philips]                DS: '90'
(2001, 1024) [Interactive]                       CS: 'N'
(2001, 1025) [Echo Time Display MR]              SH: '17'
(2001, 105f)  [Stack Sequence]   1 item(s) ---- 
   (2001, 0000) Private Creator                     UL: 88
   (2001, 0010) Private tag data                    LO: 'Philips Imaging DD 001'
   (2001, 102d) [Number of Stack Slices]            SS: 30
   (2001, 1032) [Stack Radial Angle]                FL: 0.0
   (2001, 1033) [Stack Radial Axis]                 CS: 'AP'
   (2001, 1035) [Stack Slice Number]                SS: 1
   (2001, 1036) [Stack Type]                        CS: 'PARALLEL'
   (2005, 0000) Private Creator                     UL: 244
   (2005, 0010) Private tag data                    LO: 'Philips MR Imaging DD 001'
   (2005, 0014) Private tag data                    LO: 'Philips MR Imaging DD 005'
   (2005, 1071) [Unknown]                           FL: 4.424337387084961
   (2005, 1072) [Unknown]                           FL: -11.054109573364258
   (2005, 1073) [Unknown]                           FL: 4.698903560638428
   (2005, 1074) [Unknown]                           FL: 104.5
   (2005, 1075) [Unknown]                           FL: 150.0
   (2005, 1076) [Unknown]                           FL: 131.25
   (2005, 1078) [Unknown]                           FL: -60.89842987060547
   (2005, 1079) [Unknown]                           FL: -25.10238265991211
   (2005, 107a) [Unknown]                           FL: -109.25149536132812
   (2005, 107b) [Unknown]                           CS: 'RL'
   (2005, 107e) [Unknown]                           FL: 3.5
   (2005, 1081) [Unknown]                           CS: 'AP'
   (2005, 143c) [Unknown]                           FL: -0.4000000059604645
   (2005, 143d) [Unknown]                           FL: 0.0
   (2005, 143e) [Unknown]                           FL: 0.0
   ---------
(2001, 1060) [Number of Stacks]                  SL: 1
(2001, 1061) [Unknown]                           CS: 'N'
(2001, 1062) [Unknown]                           CS: 'N'
(2001, 1063) [Examination Source]                CS: 'ELSEWHERE'
(2001, 1077) [GL TrafoType]                      CS: ''
(2001, 107b) [Acquisition Number]                IS: '8'
(2001, 1081) [Number of Dynamic Scans]           IS: '1'
(2001, 1082) [Echo Train Length]                 IS: '11'
(2001, 1083) [Imaging Frequency]                 DS: '127.743296'
(2001, 1084) [Inversion Time]                    DS: '0'
(2001, 1085) [Magnetic Field Strength]           DS: '3'
(2001, 1086) [Unknown]                           IS: '0'
(2001, 1087) [Imaged Nucleus]                    SH: '1H'
(2001, 1088) [Number of Averages]                DS: '2'
(2001, 1089) [Phase FOV Percent]                 DS: '0'
(2001, 108a) [Sampling Percent]                  DS: '0'
(2001, 108b) [Unknown]                           SH: 'S'
(2001, 10c8) Private tag data                    LO: 'MSK 46- KNEE 5.17'
(2001, 10cc) [Unknown]                           ST: ''
(2001, 10f1) [Prospective Motion Correction]     FL: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
(2001, 10f2) [Retrospective Motion Correction]   FL: [1.6999999760721821e+38, 1.6999999760721821e+38, 1.6999999760721821e+38, 1.6999999760721821e+38, 1.6999999760721821e+38, 1.6999999760721821e+38]
(2001, 116b) Private tag data                    LO: ''
(2005, 0000) Private Creator                     UL: 4374
(2005, 0010) Private tag data                    LO: 'Philips MR Imaging DD 001'
(2005, 0011) Private tag data                    LO: 'Philips MR Imaging DD 002'
(2005, 0012) Private tag data                    LO: 'Philips MR Imaging DD 003'
(2005, 0013) Private tag data                    LO: 'Philips MR Imaging DD 004'
(2005, 0014) Private tag data                    LO: 'Philips MR Imaging DD 005'
(2005, 1000) [Unknown]                           FL: 4.424337387084961
(2005, 1001) [Unknown]                           FL: -11.054109573364258
(2005, 1002) [Unknown]                           FL: 4.698903560638428
(2005, 1008) [Unknown]                           FL: -48.901275634765625
(2005, 1009) [Unknown]                           FL: -24.29806900024414
(2005, 100a) [Unknown]                           FL: -106.90972900390625
(2005, 100b) [Unknown]                           FL: 963.317626953125
(2005, 100c) [Unknown]                           FL: 0.0009265809203498065
(2005, 100d) [Unknown]                           FL: 0.0
(2005, 100e) [Unknown]                           FL: 0.5332114100456238
(2005, 100f) [Window Center]                     DS: '2631'
(2005, 1010) [Window Width]                      DS: '4574'
(2005, 1011) [Unknown]                           CS: 'M'
(2005, 1012) [Unknown]                           CS: 'N'
(2005, 1013) [Unknown]                           CS: 'NO'
(2005, 1014) [Unknown]                           CS: 'N'
(2005, 1015) [Unknown]                           CS: 'Y'
(2005, 1016) [Unknown]                           CS: 'N'
(2005, 1017) [Unknown]                           CS: 'N'
(2005, 1018) [Unknown]                           LO: ''
(2005, 1019) [Unknown]                           CS: 'N'
(2005, 101a) [Unknown]                           SS: 0
(2005, 101b) [Unknown]                           CS: 'N'
(2005, 101c) [Unknown]                           CS: 'N'
(2005, 101d) [Unknown]                           SS: 288
(2005, 101e) [Unknown]                           SH: 'compose'
(2005, 101f) [Unknown]                           SH: 'compose'
(2005, 1020) [Number of Chemical Shift]          SL: 0
(2005, 1021) [Unknown]                           SS: 1
(2005, 1022) [Unknown]                           IS: '0'
(2005, 1023) [Unknown]                           SS: 1
(2005, 1025) [Unknown]                           SS: 1
(2005, 1026) [Unknown]                           CS: 'N'
(2005, 1027) [Unknown]                           CS: 'MINIMUM'
(2005, 1028) [Unknown]                           CS: 'N'
(2005, 1029) [Unknown]                           CS: 'N'
(2005, 102a) [Unknown]                           IS: '495637986'
(2005, 102b) [Unknown]                           SS: 100
(2005, 102c) [Unknown]                           CS: 'N'
(2005, 102d) [Unknown]                           IS: '0'
(2005, 102e) [Unknown]                           CS: 'N'
(2005, 102f) [Unknown]                           CS: 'Y'
(2005, 1030) [Repetition Time]                   FL: [2231.007080078125, 0.0]
(2005, 1031) [Unknown]                           CS: 'N'
(2005, 1032) [Unknown]                           CS: ''
(2005, 1033) [Acquisition Duration]              FL: 147.24647521972656
(2005, 1034) [Unknown]                           CS: 'Y'
(2005, 1035) [Unknown]                           CS: 'PIXEL'
(2005, 1036) [Unknown]                           CS: 'N'
(2005, 1037) [Unknown]                           CS: 'N'
(2005, 1038) [Unknown]                           CS: 'N'
(2005, 1039) [Unknown]                           CS: 'N'
(2005, 103a) [Unknown]                           SH: ''
(2005, 103b) [Unknown]                           CS: 'N'
(2005, 103c) [Unknown]                           CS: 'N'
(2005, 103d) [Unknown]                           SS: 1
(2005, 103e) [Unknown]                           SL: 0
(2005, 105f) [Unknown]                           CS: 'UNKNOWN'
(2005, 1060) [Unknown]                           IS: '-1'
(2005, 1061) [Unknown]                           CS: 'NO'
(2005, 1063) [Unknown]                           SS: 0
(2005, 106e) [Unknown]                           CS: 'SE'
(2005, 106f) [Unknown]                           CS: 'MS'
(2005, 1070) [Unknown]                           LO: ''
(2005, 1081) [Unknown]                           CS: ''
(2005, 1083)  [Unknown]   1 item(s) ---- 
   (2005, 0000) Private Creator                     UL: 164
   (2005, 0010) Private tag data                    LO: 'Philips MR Imaging DD 001'
   (2005, 104e) [Unknown]                           FL: 0.0
   (2005, 104f) [Unknown]                           FL: -78.36521911621094
   (2005, 1050) [Unknown]                           FL: 66.44862365722656
   (2005, 1051) [Unknown]                           FL: -119.50460815429688
   (2005, 1052) [Unknown]                           CS: 'SLAB'
   (2005, 1053) [Unknown]                           CS: 'FH'
   (2005, 1069) [Unknown]                           FL: 4.686079502105713
   (2005, 106a) [Unknown]                           FL: -5.964495658874512
   (2005, 106b) [Unknown]                           FL: 5.141763687133789
   (2005, 106c) [Unknown]                           FL: 0.0
   (2005, 106d) [Unknown]                           FL: 26.968669891357422
   ---------
(2005, 1085)  [Unknown]   1 item(s) ---- 
   (2005, 0000) Private Creator                     UL: 172
   (2005, 0010) Private tag data                    LO: 'Philips MR Imaging DD 001'
   (2005, 1054) [Unknown]                           FL: 4.081005573272705
   (2005, 1055) [Unknown]                           FL: -10.585963249206543
   (2005, 1056) [Unknown]                           FL: 8.425114631652832
   (2005, 1057) [Unknown]                           FL: 103.25100708007812
   (2005, 1058) [Unknown]                           FL: 148.65834045410156
   (2005, 1059) [Unknown]                           FL: 121.07469177246094
   (2005, 105a) [Unknown]                           FL: -59.10819625854492
   (2005, 105b) [Unknown]                           FL: -25.680938720703125
   (2005, 105c) [Unknown]                           FL: -108.52527618408203
   (2005, 105d) [Unknown]                           CS: 'RECT_VOLUME'
   (2005, 105e) [Unknown]                           CS: 'AP'
   ---------
(2005, 1086) [Unknown]                           SS: 0
(2005, 109f) [Unknown]                           CS: ''
(2005, 10a0) [Unknown]                           FL: 0.0
(2005, 10a1) [Syncra Scan Type]                  CS: 'SENSE'
(2005, 10a2) [Unknown]                           CS: 'N'
(2005, 10a8) [Unknown]                           DS: '0'
(2005, 10a9) [Unknown]                           CS: '2D'
(2005, 10b0) [Diffusion Direction RL]            FL: 0.0
(2005, 10b1) [Diffusion Direction AP]            FL: 0.0
(2005, 10b2) [Diffusion Direction FH]            FL: 0.0
(2005, 10c0) [Unknown]                           CS: 'SE'
(2005, 1134) Private tag data                    LT: ''
(2005, 1199) [Unknown]                           UL: 1
(2005, 1200) [Unknown]                           UL: 1
(2005, 1201) [Unknown]                           UL: 0
(2005, 1213) [Unknown]                           UL: 1
(2005, 1245) [Unknown]                           SS: 2
(2005, 1249) [Unknown]                           SS: 0
(2005, 1251) [Unknown]                           SS: 0
(2005, 1252) [Unknown]                           SS: 0
(2005, 1253) [Unknown]                           SS: 0
(2005, 1256) [Unknown]                           SS: 0
(2005, 1325) [Unknown]                           CS: 'N'
(2005, 1326) [Unknown]                           FL: 0.0
(2005, 1327) [Unknown]                           CS: 'REAL'
(2005, 1328) [Unknown]                           CS: 'ORIGINAL'
(2005, 1329) [Unknown]                           FL: 50.0
(2005, 1331) [Unknown]                           SS: 0
(2005, 1334) [Unknown]                           CS: 'UNKNOWN'
(2005, 1335) [Unknown]                           CS: 'UNKNOWN'
(2005, 1336) [Unknown]                           FL: 0.0
(2005, 1337) [Unknown]                           FL: 0.0
(2005, 1338) [Unknown]                           FL: 0.0
(2005, 1340) [Unknown]                           CS: 'PRE_FT'
(2005, 1341) [Unknown]                           CS: 'UNKNOWN'
(2005, 1342) [Unknown]                           CS: 'FID'
(2005, 1343) [Unknown]                           CS: 'Y'
(2005, 1345) [Unknown]                           CS: 'NO'
(2005, 1346) [Unknown]                           CS: 'HERTZ'
(2005, 1347) [Unknown]                           FL: 0.0
(2005, 1348) [Unknown]                           CS: 'OFF'
(2005, 1349) [Unknown]                           FL: 0.0
(2005, 1351) [Unknown]                           SS: 0
(2005, 1352) [Unknown]                           SS: 0
(2005, 1354) [Unknown]                           CS: ''
(2005, 1355) [Unknown]                           FL: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
(2005, 1356) [Unknown]                           CS: 'NO'
(2005, 1357) [Unknown]                           SS: 0
(2005, 1358) [Unknown]                           LO: ''
(2005, 1359) [Unknown]                           FL: 1.0
(2005, 1360) [Unknown]                           FL: 0.0
(2005, 1362) [Unknown]                           FL: 0.0
(2005, 1363) [Unknown]                           FL: 0.0
(2005, 1364) [Unknown]                           CS: 'NO'
(2005, 1370) [Unknown]                           SS: 0
(2005, 1381) [Unknown]                           IS: '3'
(2005, 1382) [Unknown]                           UL: 1
(2005, 1391) [Unknown]                           PN: ''
(2005, 1392) [Unknown]                           IS: '0'
(2005, 1393) [Unknown]                           IS: '-1'
(2005, 1395) [Unknown]                           ST: ''
(2005, 1396) [Unknown]                           CS: 'NO'
(2005, 1397) [Unknown]                           LO: 'SRT.T-D9200.Knee'
(2005, 1398) [Unknown]                           CS: 'NO'
(2005, 1399) [Unknown]                           CS: 'NO'
(2005, 1400) [Unknown]                           CS: 'YES'
(2005, 1401) [Unknown]                           UL: 1
(2005, 1402)  [Unknown]   1 item(s) ---- 
   (0008, 0000) Group Length                        UL: 52
   (0008, 0100) Code Value                          SH: 'STUBB'
   (0008, 0102) Coding Scheme Designator            SH: 'STUBB'
   (0008, 0104) Code Meaning                        LO: 'STUBB'
   (0008, 010b) Context Group Extension Flag        CS: 'N'
   ---------
(2005, 1403) [Unknown]                           UL: 0
(2005, 1409) [Unknown]                           DS: '0'
(2005, 140a) [Unknown]                           DS: '10.6808302808302'
(2005, 140b) [Unknown]                           LO: 'normalized'
(2005, 140f)  [Unknown]   1 item(s) ---- 
   (0008, 0000) Group Length                        UL: 106
   (0008, 002a) Acquisition DateTime                DT: '20150501'
   (0008, 9123) Creator-Version UID                 UI: 1.3.46.670589.11
   (0008, 9205) Pixel Presentation                  CS: 'MONOCHROME'
   (0008, 9206) Volumetric Properties               CS: 'VOLUME'
   (0008, 9207) Volume Based Calculation Technique  CS: 'NONE'
   (0008, 9209) Acquisition Contrast                CS: 'PROTON_DENSITY'
   (0018, 0000) Group Length                        UL: 1204
   (0018, 9005) Pulse Sequence Name                 SH: 'TSE'
   (0018, 9008) Echo Pulse Sequence                 CS: 'SPIN'
   (0018, 9009) Inversion Recovery                  CS: 'NO'
   (0018, 9011) Multiple Spin Echo                  CS: 'YES'
   (0018, 9012) Multi-planar Excitation             CS: 'NO'
   (0018, 9014) Phase Contrast                      CS: 'NO'
   (0018, 9015) Time of Flight Contrast             CS: 'NO'
   (0018, 9016) Spoiling                            CS: 'NONE'
   (0018, 9017) Steady State Pulse Sequence         CS: 'NONE'
   (0018, 9018) Echo Planar Pulse Sequence          CS: 'NO'
   (0018, 9019) Tag Angle First Axis                FD: 7.23e+75
   (0018, 9020) Magnetization Transfer              CS: 'NONE'
   (0018, 9021) T2 Preparation                      CS: 'NO'
   (0018, 9022) Blood Signal Nulling                CS: 'NO'
   (0018, 9024) Saturation Recovery                 CS: 'NO'
   (0018, 9025) Spectrally Selected Suppression     CS: 'FAT'
   (0018, 9026) Spectrally Selected Excitation      CS: 'WATER'
   (0018, 9027) Spatial Pre-saturation              CS: 'SLAB'
   (0018, 9028) Tagging                             CS: 'NONE'
   (0018, 9029) Oversampling Phase                  CS: '2D'
   (0018, 9030) Tag Spacing First Dimension         FD: 7.23e+75
   (0018, 9032) Geometry of k-Space Traversal       CS: 'RECTILINEAR'
   (0018, 9033) Segmented k-Space Traversal         CS: 'PARTIAL'
   (0018, 9034) Rectilinear Phase Encode Reordering CS: 'UNKNOWN'
   (0018, 9035) Tag Thickness                       FD: 0.0
   (0018, 9036) Partial Fourier Direction           CS: ''
   (0018, 9037) Cardiac Synchronization Technique   CS: 'NONE'
   (0018, 9043) Receive Coil Type                   CS: 'MULTICOIL'
   (0018, 9044) Quadrature Receive Coil             CS: 'NO'
   (0018, 9047) Multi-Coil Element Name             SH: ''
   (0018, 9050) Transmit Coil Manufacturer Name     LO: ''
   (0018, 9051) Transmit Coil Type                  CS: 'SURFACE'
   (0018, 9053) Chemical Shift Reference            FD: [4.68, 4.68]
   (0018, 9058) MR Acquisition Frequency Encoding S US: 288
   (0018, 9059) De-coupling                         CS: 'NO'
   (0018, 9060) De-coupled Nucleus                  CS: ''
   (0018, 9062) De-coupling Method                  CS: ''
   (0018, 9064) k-space Filtering                   CS: 'RIESZ'
   (0018, 9065) Time Domain Filtering               CS: ''
   (0018, 9069) Parallel Reduction Factor In-plane  FD: 1.7000000476837158
   (0018, 9075) Diffusion Directionality            CS: 'NONE'
   (0018, 9077) Parallel Acquisition                CS: 'YES'
   (0018, 9078) Parallel Acquisition Technique      CS: 'SENSE'
   (0018, 9079) Inversion Times                     FD: 0.0
   (0018, 9080) Metabolite Map Description          ST: 'WATER'
   (0018, 9081) Partial Fourier                     CS: 'NO'
   (0018, 9085) Cardiac Signal Source               CS: ''
   (0018, 9087) Diffusion b-value                   FD: 7.23e+75
   (0018, 9089) Diffusion Gradient Orientation      FD: [7.23e+75, 7.23e+75, 7.23e+75]
   (0018, 9090) Velocity Encoding Direction         FD: [0.0, 0.0, 0.0]
   (0018, 9091) Velocity Encoding Minimum Value     FD: 0.0
   (0018, 9093) Number of k-Space Trajectories      US: 16
   (0018, 9094) Coverage of k-Space                 CS: ''
   (0018, 9101) Frequency Correction                CS: 'NO'
   (0018, 9147) Diffusion Anisotropy Type           CS: ''
   (0018, 9155) Parallel Reduction Factor out-of-pl FD: 1.0
   (0018, 9168) Parallel Reduction Factor Second In FD: 1.0
   (0018, 9169) Cardiac Beat Rejection Technique    CS: ''
   (0018, 9170) Respiratory Motion Compensation Tec CS: 'NONE'
   (0018, 9171) Respiratory Signal Source           CS: 'NONE'
   (0018, 9172) Bulk Motion Compensation Technique  CS: 'NONE'
   (0018, 9174) Applicable Safety Standard Agency   CS: 'IEC'
   (0018, 9176)  Operating Mode Sequence   3 item(s) ---- 
      (0018, 0000) Group Length                        UL: 44
      (0018, 9177) Operating Mode Type                 CS: 'STATIC FIELD'
      (0018, 9178) Operating Mode                      CS: 'IEC_FIRST_LEVEL'
      ---------
      (0018, 0000) Group Length                        UL: 28
      (0018, 9177) Operating Mode Type                 CS: 'RF'
      (0018, 9178) Operating Mode                      CS: 'IEC_NORMAL'
      ---------
      (0018, 0000) Group Length                        UL: 34
      (0018, 9177) Operating Mode Type                 CS: 'GRADIENT'
      (0018, 9178) Operating Mode                      CS: 'IEC_NORMAL'
      ---------
   (0018, 9179) Specific Absorption Rate Definition CS: 'IEC_WHOLE_BODY'
   (0018, 9180) Gradient Output Type                CS: 'DB_DT'
   (0018, 9181) Specific Absorption Rate Value      FD: 0.1288565695285797
   (0018, 9182) Gradient Output                     FD: 91.73162841796875
   (0018, 9183) Flow Compensation Direction         CS: ''
   (0018, 9199) Water Referenced Phase Correction   CS: 'NO'
   (0018, 9200) MR Spectroscopy Acquisition Type    CS: ''
   (0018, 9231) MR Acquisition Phase Encoding Steps US: 259
   (0018, 9232) MR Acquisition Phase Encoding Steps US: 1
   (0018, 9240) RF Echo Train Length                US: 11
   (0018, 9241) Gradient Echo Train Length          US: 0
   (0018, 9602) Diffusion b-value XX                FD: 7.23e+75
   (0018, 9603) Diffusion b-value XY                FD: 7.23e+75
   (0018, 9604) Diffusion b-value XZ                FD: 7.23e+75
   (0018, 9605) Diffusion b-value YY                FD: 7.23e+75
   (0018, 9606) Diffusion b-value YZ                FD: 7.23e+75
   (0018, 9607) Diffusion b-value ZZ                FD: 7.23e+75
   (0020, 0000) Group Length                        UL: 58
   (0020, 9072) Frame Laterality                    CS: 'U'
   (0020, 9254) Respiratory Interval Time           FD: 0.0
   (0020, 9255) Nominal Respiratory Trigger Delay T FD: 0.0
   (0020, 9256) Respiratory Trigger Delay Threshold FD: 7.23e+75
   (0028, 0000) Group Length                        UL: 40
   (0028, 9001) Data Point Rows                     UL: 1
   (0028, 9002) Data Point Columns                  UL: 0
   (0028, 9003) Signal Domain Columns               CS: ''
   (0028, 9108) Data Representation                 CS: ''
   (0040, 0000) Group Length                        UL: 16
   (0040, 9210) LUT Label                           SH: 'Philips'
   ---------
(2005, 1410) [Unknown]                           IS: '2147483647'
(2005, 1412) [Unknown]                           IS: '1'
(2005, 1413) [Unknown]                           IS: '1'
(2005, 1414) [Unknown]                           SL: 1
(2005, 1415) [Unknown]                           SL: 1
(2005, 1416) [Unknown]                           CS: 'MAN'
(2005, 1418) [Unknown]                           CS: ['STATIC FIELD', 'RF', 'GRADIENT']
(2005, 1419) [Unknown]                           CS: ['IEC_FIRST_LEVEL', 'IEC_NORMAL', 'IEC_NORMAL']
(2005, 141a) [Unknown]                           CS: 'SPAIR'
(2005, 141b) [Unknown]                           IS: '0'
(2005, 141c) [Unknown]                           IS: '0'
(2005, 141d) [Unknown]                           IS: '0'
(2005, 1426) [Unknown]                           CS: 'N'
(2005, 1428) [Unknown]                           SL: 0
(2005, 1429) Private tag data                    CS: ''
(2005, 142a) [Unknown]                           CS: 'INITIAL'
(2005, 142b) [Unknown]                           CS: 'INITIAL'
(2005, 142c) [Unknown]                           CS: 'PARTLY_ACCEPTED'
(2005, 142d) [Unknown]                           CS: 'INITIAL'
(2005, 142e) [Unknown]                           FL: 1.6999999760721821e+38
(2005, 142f) [Unknown]                           FL: 1.6999999760721821e+38
(2005, 1430) [Unknown]                           FL: 1.6999999760721821e+38
(2005, 1431) [Unknown]                           FL: 1.6999999760721821e+38
(2005, 1432) [Unknown]                           CS: 'N'
(2005, 1435) [Unknown]                           CS: 'N'
(2005, 1437) [Unknown]                           CS: ''
(2005, 143a) [Unknown]                           LT: 'datadefs $Revision: 51.0 $'
(2005, 143b) [Unknown]                           CS: 'N'
(2005, 143f) [Unknown]                           CS: 'N'
(2005, 1440) [Unknown]                           FL: 0.0
(2005, 1441) [Unknown]                           FL: 0.0
(2005, 1442) [Unknown]                           FL: 0.0
(2005, 1443) [Unknown]                           FL: 0.0
(2005, 1444) [Unknown]                           IS: '0'
(2005, 1445) [Unknown]                           CS: 'N'
(2005, 1446) [Unknown]                           FL: 1.6999999760721821e+38
(2005, 1447) [Unknown]                           FL: 0.0
(2005, 1448) [Unknown]                           FL: 1.6999999760721821e+38
(2005, 144d) [Unknown]                           CS: 'N'
(2005, 144e) [Unknown]                           CS: 'N'
(2005, 1492) Private tag data                    FL: 0.01897367462515831
(2050, 0000) Group Length                        UL: 16
(2050, 0020) Presentation LUT Shape              CS: 'IDENTITY'
(7fd1, 0000) Private Creator                     UL: 0
(7fe0, 0010) Pixel Data                          OW: Array of 524288 bytes

Most of the time, we are only interested in a few of these fields. Rather than dumping the whole list, we can pick and choose the ones we want.

Since one may not always remember the exact name of a data element, the pydicom library provides a handy dir() method, useful during interactive sessions at the python prompt. Using this command, we can quickly find the names of all data elements that have the word "patient" in them thusly:

In [7]:
ds1.dir("patient")
Out[7]:
['AdditionalPatientHistory',
 'ImageOrientationPatient',
 'ImagePositionPatient',
 'PatientAge',
 'PatientBirthDate',
 'PatientComments',
 'PatientID',
 'PatientName',
 'PatientPosition',
 'PatientSex',
 'PatientState',
 'PatientTransportArrangements',
 'PatientWeight']

We can now examine any of these one by one, as shown below:

In [8]:
ds1.PatientName # show patient name
Out[8]:
'Finn, Huckleberry'
In [9]:
ds1.PatientSex # show patient gender
Out[9]:
'M'
In [10]:
ds1.AcquisitionDate # show date of study acquisition
Out[10]:
'18840101'
In [11]:
ds1.PatientAge # show patient's age at time of scan
Out[11]:
'14'

Changing Data Elements in a DICOM file

Sometimes, data (such as age) is sometimes entered incorrectly by a data entry minion. One way to check this is to see if the age entered is congruent with the date of birth and the date of study. We can do this with the following Python code:

In [14]:
DOB = datetime.strptime(ds1.PatientBirthDate, "%Y%m%d")
StudyDate = datetime.strptime(ds1.StudyDate, "%Y%m%d")
Age = (StudyDate - DOB).days/365

print ("Age = ", Age)
Age =  14.008219178082191

Sometimes a lot of time has passed since an image was done, and we might like to know how old our patient is currently. We can calculate this by subtracting the date of birth from the current date. In this case, the DICOM header suggests that this patient was born on January 1, 1870. The following Python code will grab today's date and do the calculation:

In [17]:
DOB = datetime.strptime(ds1.PatientBirthDate, "%Y%m%d")
now = datetime.now()
Age = (now - DOB).days/365

print ("Current age = ", Age, "years")
Current age =  147.67945205479452 years

For an timeless literary character such as Huckleberry Finn, 147+ years does not seem excessive. For most actual patients, a result like this suggests a data entry error. If a quick audit were to show that the actual birthdate were July 4, 1970, we could fix the incorrect birthdate with the following code:

In [18]:
PatientBDActual = '19700704' 

ds1.PatientBirthDate = PatientBDActual # change birthdate

We can change any other DICOM data field in a similar manner.

Once we have made all of the changes we desire, our next step is to save all of our changes in a new DICOM image file, which we will call "Knee_MR_corrected.dcm".

In [19]:
ds1.save_as("Knee_MR_corrected.dcm") # save as new file with corrected birthdate

3. Anonymizing a DICOM image file

In order to comply with the Health Insurance Portability and Accountability Act (HIPAA), it is occasionally necessary to anonymize the protected health information (PHI) contained in a DICOM image. Guidance as to which data elements constitute PHI can be found at the U. S. Health & Human Services website.

One can anonymize a DICOM image file by changing the PHI fields to blank or neutral values, as shown in the section above.

However, one can also completely delete the PHI fields from the DICOM image file using the "del" command. The lines of code shown below demonstrate how one might delete the fields for the following PHI elements:

  1. Patient name
  2. Accession number
  3. Medical record number
  4. Date of Birth
In [20]:
# delete the following DICOM data elements
del ds1.PatientName
del ds1.AccessionNumber
del ds1.PatientID
del ds1.PatientBirthDate

ds1.save_as("Knee_MR_anonymized.dcm") # save as new file with deleted PHI

4. Anonymizing a folder of DICOM image files

Anonymizing a single DICOM image file by hand can be tedious enough. Anonymizing a whole folder of DICOM images is cruel and unusual punishment. The following code will allow you to anonymize an entire folder of DICOM images without breaking a sweat. You're welcome.

The following code will look in a folder called "files_to_anonymize", which is at the same location as this DICOM toolbox notebook.

When you run the following code, it will do the following:

  1. create a list of every file in the "files_to_anonymize" folder
  2. sequentially open each DICOM file
  3. delete four PHI fields from the DICOM header
  4. save the newly anonymized DICOM file, overwriting the original
  5. print out the name of each DICOM file as it is processed

Caveat: If this program doesn't find any DICOM images in the folder called "files_to_anonymize", it will give an error message. It will also give an error message if a DICOM image lackss any of the four PHI data elements for name, accession number, patient ID or birthdate (i.e. if they have already been anonymized).

You are welcome to edit the list of data elements in the code below to delete any data elements you desire.

In [188]:
# grab the name of every file in our folder
for filename in glob.iglob('files_to_anonymize/*.dcm', recursive=True):
    # read in a DICOM file into memory
    ds = dicom.read_file(filename, force=True)
    
    # get the name of the folder the dicomfiles are stored in
    foldername=os.path.basename(os.path.dirname(os.path.dirname(filename)))
    
    #delete patient name, accesion number, patient ID and patient birthdate
    del ds.PatientName
    del ds.AccessionNumber
    del ds.PatientID
    del ds.PatientBirthDate

    # overwrite the original file
    dicom.write_file(filename,ds)
    
    # output progress to the screen
    print(filename)
files_to_anonymize/CT_chest.dcm
files_to_anonymize/Hand.dcm
files_to_anonymize/Knee_MR.dcm
files_to_anonymize/knee_radiograph.dcm

5. Saving a DICOM image in another format

There are a lot of good reasons for converting a DICOM image into another format, such as the .JPG, .PNG or .TIFF formats. The .JPG and .PNG formats are perfect for use with a website. When submitting an image for publication, journals often request that the image file be submitted in .TIFF format.

The following code will take the image data from the DICOM pixel array and save a copy in the .JPG, .PNG and .TIFF formats:

In [22]:
plt.imsave('knee_MR.jpg', ds1.pixel_array, cmap=plt.cm.gray)
plt.imsave('knee_MR.png', ds1.pixel_array, cmap=plt.cm.gray)
plt.imsave('knee_MR.tif', ds1.pixel_array, cmap=plt.cm.gray)

6. Optimizing a DICOM image

The Scientific Python (SciPy) library contains a number of handy image processing routines as part of the scikit-image library. These routines will come pre-installed as part of the Anaconda or Enthought Python distributions. In addition to scikit-image, we will also use some of the routines from the Numerical Python (numpy) library.

Let us look again at our original knee MR, and see how we might optimze it.

In [23]:
ds1 = dicom.read_file("Knee_MR.dcm")  # read the knee MR image into memory

# tell matplotlib to display our images as 6 x 6 inch image, with resolution of 100 dpi
plt.figure(figsize = (6,6), dpi=100) 

# tell matplotlib to display our image, using a gray-scale lookup table.
plt.imshow(ds1.pixel_array, cmap=plt.cm.gray) 
Out[23]:
<matplotlib.image.AxesImage at 0x110e2d9b0>

Image histograms can be useful

This knee MR is nice-looking, but it is a bit dark. Let's have a look at the image histogram. Histograms can often give us some helpful clues as the best way to optimize an image.

In [28]:
plt.hist(ds1.pixel_array.flatten(), bins=64) # calculate a histogram of our image
plt.show() # display that histogram

print ("pixel array = ", ds1.pixel_array.shape)
print("minimum value = ", np.amin(ds1.pixel_array)) # find minimum pixel value in the image array
print("maximum value = ", np.amax(ds1.pixel_array)) # find maximum pixel value in the image array
pixel array =  (512, 512)
minimum value =  0
maximum value =  513

Our MR image has 512 * 512 = 262,144 pixels. The pixels with the lowest value (0 in this case) are displayed as black. The pixels with the highest value (513 in this case) are displayed as white. All other values are assigned a value somewhere on a linear scale between black and white.

This histogram of the our image shows that about 67,000 of the pixels are black (value = 0), as shown by the tallest bar over to the far left. Although we know that our highest pixel value is 513, this histogram actually doesn't show much visible image information to the right of 260. The histogram also shows us that pixel values of 260 will be mapped to a shade of gray halfway between black and white.

Window and level settings (aka contrast stretching)

Besides useful anatomical details, medical images often contain other things that are less relevant (the air outside the patient, right/left markers, etc.). Depending on how the image was obtained, a number of gray shades may be devoted to these less interesting structures. We would therefore like to adjust our image so that it is optimized for the stuctures we consider useful.

As a rule of thumb, gray-scale images tend to look better when the left-hand edge of the useful pixel values is mapped to black and the right-hand edge of the useful pixel values is mapped to white. When one does this on a workstation, it is called "windowing" and "leveling". One might also call this "contrast stretching".

We will use the exposure.rescale_intensity function from the sci-kit image library to do the heavy lifting for us. We will set the lower and upper edges of our window to various values and see how that affects the image. We could use actual pixel values to set the edges of our window. However, rather than having to worry about the exact values, I find it easier to set the window edges using percentiles of the pixel data.

In the example below, we will leave the lower edge of the window at the 0th percentile, but drop the upper edge of the window to the 99.5th percentile.

In [32]:
# Contrast stretching try 1
plt.figure(figsize = (6,6), dpi=100)

p_lo, p_hi = np.percentile(ds1.pixel_array, (0, 99.5))

img_rescale_1 = exposure.rescale_intensity(ds1.pixel_array, in_range=(p_lo, p_hi))

figure = plt.imshow(img_rescale_1, cmap=plt.cm.gray)

That rescaled image looks a lot snappier to my eye.

Let's see what the histogram looks like for this re-windowed image:

In [33]:
plt.hist(img_rescale_1.flatten(), bins=64)
plt.show()
print("p_lo = ", p_lo)
print("p_hi = ",p_hi)
p_lo =  0.0
p_hi =  253.0

From the histogram, we can see that the 99.5th percentile is equivalent to a pixel value of 253. All pixels with values greater than or equal to 253 are mapped to white. The histogram now shows that the window edges are indeed now very close to the edges of the visible image data.

Next, let's try dropping the upper edge of the window down to the 95th percentile.

In [34]:
# Contrast stretching try 2
plt.figure(figsize = (6,6), dpi=100)

p_lo, p_hi = np.percentile(ds1.pixel_array, (0, 95))
img_rescale_2 = exposure.rescale_intensity(ds1.pixel_array, in_range=(p_lo, p_hi))

figure = plt.imshow(img_rescale_2, cmap=plt.cm.gray)