Accessing data in DICOM files
By Jeff Mather, MathWorks
The DICOM (Digital Imaging and Communication in Medicine) format describes how to compose messages to send between imaging modalities (e.g., Computed Tomography (CT), Magnetic Resonance (MR), and ultrasound devices) and defines a set of operations for transmitting them across a network. These messages can also be written to files for offline storage on a picture archiving system, CD, or other type of storage device. DICOM-formatted messages combine images and metadata to create a rich description of a medical imaging procedure. This format is extremely detailed, with a specification that is more than 2,500 pages long.
MATLAB and the Image Processing Toolbox provide easy access to DICOM data. Accessing data in DICOM files becomes as easy as working with TIFF or JPEG images. This article presents examples of using DICOM and provides background information about the format.
Before DICOM: Chaos
DICOM has significantly improved communication between medical devices and lowered the cost and complexity of integrating hardware and software solutions. Before DICOM, each manufacturer used proprietary image formats and communications protocols to connect their hardware solutions with third-party products. Integrating medical hardware and software from different vendors meant translating from one vendor's protocols to another's. This process was chaotic and fraught with difficulty. A cottage industry developed to provide data translation services.
With the advent of DICOM as a formal standard in 1993, one protocol replaced many protocols and formats. DICOM is the common format, easing integration of solutions from different vendors. For example, it is possible to integrate a MR scanner from GE Medical Systems with a picture archive system (PACS) from Agfa and another vendor's film printer without using translation devices. Integration isn't limited to just hardware. Software such as MATLAB that supports DICOM can share images with all of these devices, provided that each of the hardware devices has implemented the necessary DICOM services.
A Simple First Example
In medical imaging, a patient is subject to an imaging study, which may contain multiple series of images. Each series is performed on a single modality such as an MR, CT, or X-ray device and can have multiple related images. Suppose that we have a study consisting of a series of 20 transverse MRI brain images and we want to read them into MATLAB. (These 20 images are stored in 20 DICOM files with names such as brain_017.dcm, which you can download from MATLAB Central if you want to run the examples.) Let's suppose we know that each image is 256-by-256 and contains signed 16-bit data. We can read the series with the following code:
% Preallocate the 256-by-256-by-1-by-20 image array. X = repmat(int16(0), [256 256 1 20]);
% Read the series of images. for p=1:20 filename = sprintf('brain_%03d.dcm', p); X(:,:,1,p) = dicomread(filename); end
% Display the image stack. montage(X,)
After running this code, the MATLAB workspace contains a 4-D array with the image data, and a plot of the MR slices appears.
You can use MATLAB and the Image Processing Toolbox to perform multiple tasks with this data. For example, MATLAB provides sophisticated volume visualization techniques to reconstruct a 3-D surface from these slices and then apply surface and lighting effects. The example in the Help section for the
isocaps function shows this implemented. The
tformarray functions in the Image Processing Toolbox make it easy to extract slices in different orientations from the transverse data. For example, the "Extracting Slices from a 3-Dimensional MRI Data Set" example shows how to extract saggital slices from a similar dataset. You can also use the morphology functions within the Image Processing Toolbox to perform operations such as image segmentation, feature extraction, and image statistics. Alternatively, you can write your own functions to perform volume estimation, shrinkwrapping, etc.
Accessing DICOM Metadata
In the previous example, we made several assumptions as we preallocated the storage array. All of these assumptions were based on metadata that exists in the DICOM file. Furthermore, the values of the image pixels are limited to a narrow band in the total possible dynamic range of the image, so we had to pass an empty array as a special argument to
montage to rescale the data. Let's use the metadata attributes in the DICOM files to (1) intelligently preallocate our array and (2) rescale the data values to fill the 16-bit dynamic range.
Because all images in a series must have the same dimensions and bit-depth, we only need to get the metadata from one image in the series to preallocate the array. The Image Processing Toolbox function
dicominfo returns the metadata from a DICOM file.
As you can see, there are many metadata values, or attributes. The values for "Rows," "Columns," and "BitsStored" tell us exactly what we need to know, and we can rewrite the code that reads the image stack.
nRows = info.Rows; nCols = info.Columns; nPlanes = info.SamplesPerPixel; nFrames = 20; % The number of files in the directory
X = repmat(int16(0), [nRows, nCols, nPlanes, nFrames]);
for p = 1:nFrames fname = sprintf('brain_%03d.dcm', p); X(:,:,:,p) = dicomread(fname); end
We still have to take for granted that the image contains signed data&msdash;a "PixelRepresentation" value of "1" indicates that type of data-but the rest of the information that we need is easily obtained. We can use this metadata along with the
imlincomb function in the Image Processing Toolbox to rescale the image data to fill the entire 16-bit dynamic range. The linear combination to rescale the grayscale values is "y = (x - b) * m", where b is the minimum x value and m is a constant ratio derived from the input and output ranges.
% Keep track of the minimum and maximum pixel values. minPixels = repmat(0, [1, nFrames]); maxPixels = repmat(0, [1, nFrames]);
for p = 1:nFrames fname = sprintf('brain_%03d.dcm', p); info = dicominfo(fname); minPixels(p) = info.SmallestImagePixelValue; maxPixels(p) = info.LargestImagePixelValue; end
% Rescale image to start at 0. b = min(minPixels); m = 2^16/(max(maxPixels) - b); Y = imlincomb(m, X, -(m * b), 'uint16');
Details about DICOM Metadata
As shown in the previous example, a typical DICOM file contains numerous attributes. The reason for this is that DICOM messages encapsulate all of the information about a medical imaging procedure, including details about the patient, study, imaging modality, and image series in addition to the image frame stored in the file. Together, all of these attributes comprise an Information Object.
The DICOM specification contains numerous Information Object Definitions (IODs), such as MR Image, Ultrasound Multiframe Image, and Radiotherapy Plan. The DICOM files in the examples above contain MR Image Information Objects.
dicomread understands most IODs that are listed in the DICOM specification.
IODs are defined in terms of smaller functional units, or modules, which correspond to specific real-world objects, such as patients, imaging equipment, etc. The hundred-or-so modules in DICOM describe everything that could be combined to make a DICOM information object. For example, the following table lists the modules that constitute an MR Image IOD:
Modules in the MR Image IOD:
Module Description Patient Details about the patient General Study General information about the study, a set of imaging procedures Patient Study (U) Information about the patient at the time of the study General Series General information about one particular imaging procedure Frame of Reference Information to spatially relate images in a series General Equipment General information about the image modality that produced the series General Image Details that identify and describe an image within the series Image Plane Slice thickness/location/spacing and other orientation details Image Pixel The actual image pixels and information on how to interpret them Contrast/Bolus (C) Details about medication given at the time of imaging MR Image Values specific to magnetic resonance imaging Overlay Plane (U) Graphics or bitmapped text to display with a particular image VOI LUT (U) Information to transform the contrast or intensity of the image SOP Common Date/time of message creation and other generic DICOM details
Some modules, such as Patient, General Study, General Equipment, and Image Pixel, are found in many IODs. Other modules appear only in specific IODs. The MR Image module, for example, is only part of the MR Image IOD.
The IOD contains modules that describe the patient, study, series, and images for a particular medical imaging procedure. Also, notice that some modules have a "(C)" or "(U)" near their name, which means that for this IOD they are "conditionally required" or "user optional" modules; the conditional and user optional modules may or may not appear in every MR Image IOD. For example, the Contrast/Bolus module will only appear if medication is given at the time of imaging, and the VOI LUT module does not have to be implemented by the device that writes the DICOM file.
All of the modules and attributes are defined in PS 3.3 of the DICOM specification, which are available online from the National Electrical Manufacturer's Association. Additionally, all of the defined attributes are listed in a data dictionary. Vendors sometimes define private attributes that are specific to their hardware. While you do not need to do anything special to read private attributes with
dicominfo, if you want to provide additional information about attributes that are not part of the DICOM specification, you can provide your own data dictionary.
Writing DICOM Files
We will now create a new DICOM file. Writing a new file requires an image and metadata. We created a new image with the scaled data in one of the examples above, and
dicominfo will help us create the metadata we need.
To write a DICOM file, simply use
dicomwrite in the Image Processing Toolbox. Currently, this function supports creating Secondary Capture (SC) Image IODs, which contain all of the pixel data and metadata necessary for correctly interpreting the image. Essentially, an SC image is similar to what you would generate with a framegrabber, or if you had generated the image yourself from scratch or from another image (as in the example above). Metadata about the patient, image, and study will be present, but information about the original hardware that produced the image will not.
To write the tenth frame of the scaled image using default metadata to a new file, use
dicomwrite with its basic syntax:
frame = Y(:,:,:,10); filename = 'brain_scaled_10.dcm'; dicomwrite(frame, filename)
In this example,
dicomwrite infers the metadata that is required, filling in blank values where appropriate. To override default values, provide
dicomwrite with a structure containing attributes:
info = dicominfo('brain_001.dcm'); dicomwrite(frame, filename, info)
dicomwrite picks the values that apply to the Secondary Capture IOD and ignores the rest. When
dicomwrite makes a new file, it is actually performing two operations. First, it creates a Secondary Capture information object. Then it encodes the information object's attributes, turning them into a stream of bytes that are written to the output file. This last step demonstrates the DICOM concept of services.
A service provides a set of concrete actions to perform on objects. Common services include Storage, Print Management, Verification, and Query/Retrieve. When dealing with network messages, services are implemented by adding extra attributes to the message and then sending a series of instructions to the receiving machine or application, which deciphers the extra attributes to figure out what to do with the message. When working with DICOM files, the attributes are added to the file, and writing or reading the file replaces the transfer of instructions.
Writing a file containing DICOM data is very much like performing the Storage service. Essentially, the IOD's attributes plus those for the Storage service are combined and "frozen" when written to disk. Reading the file "thaws" the IOD and service attributes, and the entire context of what to do with the information is preserved.
Encoding rules found in the DICOM standard provide the algorithm for transforming attributes into a series of bytes to be transmitted or stored. Different byte-ordering schemes can be used during encoding, and image pixels can be compressed using numerous techniques, such as JPEG or run-length encoding. In the calls to
dicomwrite above, the files are encoded using so-called "implicit VR, little endian" style, and the pixels are not compressed.
A host of Transfer Syntaxes unambiguously define how to decode a DICOM message. One of these transfer syntaxes appears at the beginning of a DICOM network transmission or at the start of a DICOM file. If both the sender/writer and receiver/reader support the same transfer syntax, communication proceeds. Otherwise, communication fails. The DICOM features in MATLAB and the Image Processing Toolbox support the most commonly used transfer syntaxes.
With all of these possibilities-IODs, optional modules, services, and transfer syntaxes-it can be difficult to know exactly how well two modalities will interact. Implementing a service requires knowing which attributes to send or receive. Furthermore, making the service useful frequently requires knowing what kind of data to put into attributes and verifying that the information is correct. Consequently, few manufacturers support the full set of "Service-Object Pairs" that are possible in DICOM. In addition, different applications support different transfer syntaxes.
Fortunately, every application that implements part of DICOM should know what it supports. Manufacturers publish the information about the services, IODs, and transfer syntaxes that they support in DICOM conformance statements. By comparing statements from two different vendors, you can identify whether the two applications can share information.
Limitless Possibilities with DICOM
DICOM makes it easy to acquire and put medical images into a file. It is becoming more prevalent in the medical field.
Many medical device manufacturers and software manufacturers are adding DICOM to just about any product that can work with medical images and data.
Using MATLAB with the Image Processing Toolbox provides easy access to medical images, modality metadata, and patient information within DICOM files. They also provide numerical and image processing algorithms, GUI-building tools, and visualization techniques. With MATLAB, the Image Processing Toolbox, and DICOM it is possible to quickly view medical images, design and test new modalities, and create GUI-driven medical image analysis systems.