Skip to content

Reading DICOM images in R

May 22, 2013

The R packages oro.dicom and oro.nifti [1] provide the ability to import and visualise medical images that have been stored as DICOM [2] or ANALYZE™/NIfTI [3] files. This is handy because DICOM is widely used for clinical data, while NIfTI is a more compact format that stores only 2 files per 3D volume, rather than dozens.

library(oro.dicom)
dcmImages <- readDICOM("/dev/DICOMRT2", verbose = TRUE,
                       recursive = FALSE, exclude = "sql")

## 412 files to be processed by readDICOM()
##
|
|=================================================================| 100%

A lot of meta-data is associated with each image file, although in the case of de-identified data most of it will be masked out. Nevertheless, the fields that we are interested in for image analysis are present:

dcm.info <- dicomTable(dcmImages$hdr)
length(names(dcm.info))

## [1] 137

unique(dcm.info["0008-0008-ImageType"])

## 0008-0008-ImageType
DERIVED PRIMARY AXIAL CT_SOM5 SPI
ORIGINAL PRIMARY AXIAL
<NA>

unique(dcm.info["0018-1110-DistanceSourceToDetector"])

## 0018-1110-DistanceSourceToDetector
1040
1502.15787247627
<NA>

unique(dcm.info["0018-1130-TableHeight"])

## 0018-1130-TableHeight
198
125
<NA>

All of the image data is also available:

image(t(dcmImages$img[[1]]), col = grey(0:64/64), axes = FALSE,
      xlab = "", ylab = "")

DICOM slice

A 3D image, such as a CT or MRI, is comprised of multiple DICOM files, one for each slice. Therefore, we need to loop through the files to reconstruct the 3D volume and save it to disk as a NIfTI file:

system.time(for (stack in unique(substring(rownames(dcm.info), 15, 20))) {
    if (substring(stack, 1, 2) == "CT") {
        print(stack)
        index <- which(substring(rownames(dcm.info), 15, 20) == stack)
        dcm.stack <- list(hdr = dcmImages$hdr[index], img = dcmImages$img[index])
        dcm.nifti <- dicom2nifti(dcm.stack, DIM = 3, descrip = c("Manufacturer", 
            "ManufacturersModelName"))
        print(dcm.nifti)
        writeNIfTI(dcm.nifti, paste0("NIfTI/", stack))
    }
})

## [1] "CT4693"
## NIfTI-1 format
## Type : nifti
## Data Type : 4 (INT16)
## Bits per Pixel : 16
## Slice Code : 0 (Unknown)
## Intent Code : 0 (None)
## Qform Code : 2 (Aligned_Anat)
## Sform Code : 2 (Aligned_Anat)
## Dimension : 512 x 512 x 86
## Pixel Dimension : 1.27 x 1.27 x 3
## Voxel Units : mm
## Time Units : sec

The oro.nifti package also provides some useful visualisations:

orthographic(dcm.nifti, col.crosshairs = "green")

orthographic projection

image(dcm.nifti)

light box

References

[1]: B Whitcher, V J Schmid & A Thorton (2011) Working with the DICOM and NIfTI Data Standards in R J Stat Soft 44(6)

[2]: Digital Imaging and Communications in Medicine (DICOM)

[3]: Neuroimaging Informatics Technology Initiative (NIfTI)

Advertisements

From → Imaging, R

4 Comments
  1. If you want to run the above code on the example DICOM-RT file from Jason Dowling’s paper (Inisght Journal, 2013) then you need to make a couple of changes:

    dcmImages <- readDICOM("/dev/ITK4SampleDCMRT", verbose = TRUE,recursive = FALSE, exclude = "sql")
    dcm.info <- dicomTable(dcmImages$hdr)

    system.time(for (stack in unique(substring(rownames(dcm.info), 22, 30))) {
    if (substring(stack, 1, 2) == "MR") {
    print(stack)
    index <- which(substring(rownames(dcm.info), 22, 30) == stack)
    dcm.stack <- list(hdr = dcmImages$hdr[index], img = dcmImages$img[index])
    dcm.nifti <- dicom2nifti(dcm.stack, DIM = 3, descrip = c("Manufacturer",
    "ManufacturersModelName"))
    print(dcm.nifti)
    writeNIfTI(dcm.nifti, paste0("NIfTI/", stack))
    }
    })

    • 61 files to be processed by readDICOM()

      [1] “MR.1.2.84”
      NIfTI-1 format
      Type : nifti
      Data Type : 4 (INT16)
      Bits per Pixel : 16
      Slice Code : 0 (Unknown)
      Intent Code : 0 (None)
      Qform Code : 2 (Aligned_Anat)
      Sform Code : 2 (Aligned_Anat)
      Dimension : 256 x 256 x 60
      Pixel Dimension : 1.48 x 1.48 x 3
      Voxel Units : mm
      Time Units : sec
      user system elapsed
      1.74 0.38 2.11

Trackbacks & Pingbacks

  1. handling DICOM-RT structure sets in oro.dicom | Matt Moores
  2. Interactive image stacks in R | Matt Moores

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Richard Everitt's blog

Computational Bayesian statistics

Let's Look at the Figures

David Firth's blog

Nicholas Tierney

Computational Bayesian statistics

One weiRd tip

Computational Bayesian statistics

Series B'log

discussion blog for JRSS Series B papers

Mad (Data) Scientist

Musings, useful code etc. on R and data science

R-bloggers

R news and tutorials contributed by (750) R bloggers

Another Astrostatistics Blog

The random musings of a reformed astronomer ...

Darren Wilkinson's research blog

Statistics, computing, data science, Bayes, stochastic modelling, systems biology and bioinformatics

CHANCE

Computational Bayesian statistics

StatsLife - Significance magazine

Computational Bayesian statistics

(badness 10000)

Computational Bayesian statistics

Igor Kromin

Computational Bayesian statistics

Statisfaction

I can't get no

Xi'an's Og

an attempt at bloggin, nothing more...

Sam Clifford

Postdoctoral Fellow, Bayesian Statistics, Aerosol Science

Bayesian Research & Applications Group

Frontier Research in Bayesian Methodology & Computation

%d bloggers like this: