Get Images Out of DICOM Format Quickly

Provides tools to sort DICOM-format medical image files, and convert them to NIfTI-1 format.


CRAN version Build Status Build status Coverage Status

DICOM, for Digital Imaging and Communications in Medicine, is the highly complex standard by which medical imaging devices such as magnetic resonance (MR) and computed tomography (CT) scanners communicate. Importantly for medical imaging research, DICOM defines the format in which images are first created when a subject is scanned. The complexity of DICOM, and the high degree of variation in how it is implemented by hardware vendors, makes it difficult and error-prone to work with. The NIfTI-1 file format has emerged as a simpler, more interoperable standard for medical images, and generally researchers want to convert their images to this format as soon as possible.

The divest package is a variant of Chris Rorden's excellent dcm2niix DICOM-to-NIfTI conversion tool, which has been minimally restructured to support an in-memory interface to R. It links the speed and reliability of the popular dcm2niix to the R-native NIfTI tools provided by the RNifti package.

The package is on CRAN, and the latest development version of the package can always be installed from GitHub using the devtools package.

# install.packages("devtools")
devtools::install_github("jonclayden/divest")

Please note that, like dcm2niix, the divest package is to be used for research purposes only, and is not a clinical tool. It comes with no warranty.

Usage

The package's key function is readDicom, which scans a directory containing DICOM files, stacks related data into merged 3D or 4D images where appropriate, and returns a list of niftiImage objects. For example,

library(divest)
path <- system.file("extdata", "raw", package="divest")
images <- readDicom(path, interactive=FALSE, verbosity=-1)
## [dcm2niix info]  Warning: all images appear to be a single slice - please check slice/vector orientation
## [dcm2niix WARNING] Weird CSA 'ProtocolSliceNumber' (System/Miscellaneous/ImageNumbering reversed): VALIDATE SLICETIMING AND BVECS
## [dcm2niix WARNING] Check that 2D images are not mirrored.

The conversion is interactive by default, prompting the user to select which series to convert, but here we simply convert everything non-interactively. The minimal test dataset provided with the package contains two images from each of two acquisitions. (It is incomplete, hence the warnings.) We can see the basic properties of a converted composite image by printing it.

images[[2]]
## Internal image: "T0_N_S8"
## - 96 x 96 x 1 x 2 voxels
## - 2.5 x 2.5 x 5 mm x 4.1 s per voxel

Additional properties of the scanning sequence, such as the magnetic field strength used, are stored in attributes if they can be deduced from the DICOM files.

attributes(images[[2]])
## $imagedim
## [1] 96 96  1  2
## 
## $pixdim
## [1] 2.5 2.5 5.0 4.1
## 
## $pixunits
## [1] "mm" "s" 
## 
## $.nifti_image_ptr
## <pointer: 0x7fc6ea5281b0>
## 
## $class
## [1] "internalImage" "niftiImage"   
## 
## $modality
## [1] "MR"
## 
## $imageType
## [1] "ORIGINAL_PRIMARY_M_ND_NORM"
## 
## $fieldStrength
## [1] 1.494
## 
## $flipAngle
## [1] 90
## 
## $echoTime
## [1] 112
## 
## $repetitionTime
## [1] 4100
## 
## $phaseEncodingSteps
## [1] 72
## 
## $phaseEncodingLines
## [1] 96
## 
## $pixelBandwidth
## [1] 900
## 
## $phaseEncodingDirection
## [1] "j"
## 
## $phaseEncodingSign
## [1] -1

If desired, functions from the RNifti package can be used to inspect and modify the details of the converted NIfTI image, or to write it to file.

library(RNifti)
dumpNifti(images[[2]])
## NIfTI-1 header
##     sizeof_hdr: 348
##       dim_info: 57
##            dim: 4  96  96  1  2  1  1  1
##      intent_p1: 0
##      intent_p2: 0
##      intent_p3: 0
##    intent_code: 0
##       datatype: 4
##         bitpix: 16
##    slice_start: 0
##         pixdim: -1.0  2.5  2.5  5.0  4.1  0.0  0.0  0.0
##     vox_offset: 352
##      scl_slope: 1
##      scl_inter: 0
##      slice_end: 0
##     slice_code: 0
##     xyzt_units: 10
##        cal_max: 0
##        cal_min: 0
## slice_duration: 0
##        toffset: 0
##        descrip: TE=1.1e+02;Time=0.000;phase=1
##       aux_file: 
##     qform_code: 1
##     sform_code: 1
##      quatern_b: 0
##      quatern_c: 1
##      quatern_d: 0
##      qoffset_x: 122.0339
##      qoffset_y: -101.2288
##      qoffset_z: -55.42373
##         srow_x: -2.5000  0.0000  0.0000  122.0339
##         srow_y: 0.0000  2.5000  0.0000  -101.2288
##         srow_z: 0.00000  0.00000  5.00000  -55.42373
##    intent_name: 
##          magic: n+1
writeNifti(images[[2]], "stack")

It is also possible to obtain information about the available DICOM series without actually performing the conversion. The scanDicom function returns a data frame containing certain information about each series.

names(scanDicom(path))
## [dcm2niix info] Found 4 DICOM image(s)
##  [1] "label"             "rootPath"          "files"            
##  [4] "seriesNumber"      "seriesDescription" "patientName"      
##  [7] "studyDate"         "echoTime"          "repetitionTime"   
## [10] "echoNumber"        "phase"             "diffusion"

Elements of this data frame which can't be determined from the DICOM metadata, for example due to anonymisation, will take the conventional NA value to indicate missing data.

News

Significant changes to the divest package are laid out below for each release.

===============================================================================

VERSION 0.7.1

  • There is no longer a failure if the user does not have write access to the DICOM directory being read from.
  • R's temporary directory, rather than a hidden directory within the source folder, is now used for temporary copies of files when reading subsets.

===============================================================================

VERSION 0.7.0

  • Additional attributes for series number and description, sequence name, protocol name, slice thickness and slice spacing are now captured from DICOM files during conversion.
  • readDicom() now accepts a "subset" argument, even when a path is given rather than a data frame. In this case scanDicom() is called first, and then the requested subset is converted.
  • The package is now compatible with an upcoming change in the RNifti package.
  • Further upstream improvements.

===============================================================================

VERSION 0.6.1

  • The C++ compiler configuration is now properly detected by the configure script.
  • Warnings from GCC8 and Valgrind have been addressed.

===============================================================================

VERSION 0.6.0

  • Upstream improvements, particularly for Philips data, have been integrated.
  • The package's continuous integration tests now check it against the dcm_qa dataset (see https://github.com/neurolabusc/dcm_qa).
  • A workaround has been added for certain undefined behaviour.

===============================================================================

VERSION 0.5.0

  • The new sortDicom() function can be used to sort a directory of DICOM files into subdirectories corresponding to individual acquisitions.
  • It is now possible to read and convert individual files to NIfTI-1 format. This will happen whenever an argument to readDicom() is a file rather than a directory.
  • JPEG-encoded versions of the test files are now provided, to test the package more thoroughly.
  • Additional attributes, such as inversion time, patient weight and slice timing, are now captured, while the calculations for some others have changed, to match the current version of dcm2niix. Echo train duration and the "EPI factor" have been removed (see https://github.com/rordenlab/dcm2niix/issues/127).
  • The scanDicom() function now properly concatenates attributes when called with multiple paths.

===============================================================================

VERSION 0.4.1

  • Fixes for Solaris and OpenJPEG compatibility.

===============================================================================

VERSION 0.4.0

  • The data frame returned from scanDicom() can now be passed to readDicom(), and the latter gains a "subset" argument, which can be used to select a subset of the series to convert.
  • The results of scanDicom() now also include the number of files associated with each series, and whether or not diffusion direction metadata is available.
  • Additional attributes containing information about the acquisition are now extracted from the ASCII CSA header in Siemens EPI files.

===============================================================================

VERSION 0.3.0

  • A configure script has been added to detect OpenJPEG or JasPer libraries. If either is available, the package will be able to read DICOM data encoded using the JPEG2000 codec.
  • The readDicom() function gains a "labelFormat" option, which allows the format of image labels to be customised.
  • A new "verbosity" level of -1 is now supported, which filters all but warning and error messages from dcm2niix's output.
  • Spurious date and time information should no longer be returned.

===============================================================================

VERSION 0.2.0

  • The readDicom() function is now interactive in suitable sessions, allowing the user to choose which DICOM series to convert.
  • The new scanDicom() function allows the DICOM files in a directory to be scanned without performing any conversion. It returns a data frame containing information about the available scan series.
  • Both functions now search the current working directory by default.
  • Diffusion b-values and gradient vectors, and patient information, are now additionally stored as attributes in returned image objects.
  • Image cropping and forced stacking options from dcm2niix are now exposed to the R interface.
  • Gantry tilt correction is now applied to CT images where needed. (Reported by John Muschelli.)
  • Phase encoding attributes are now handled more robustly.

===============================================================================

VERSION 0.1.2

  • The package now behaves correctly on big-endian systems.

===============================================================================

VERSION 0.1.1

  • A test has been made more robust.

===============================================================================

VERSION 0.1.0

  • First public release.

===============================================================================

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.

install.packages("divest")

0.7.2 by Jon Clayden, 2 months ago


https://github.com/jonclayden/divest


Report a bug at https://github.com/jonclayden/divest/issues


Browse source code at https://github.com/cran/divest


Authors: Jon Clayden [aut, cre] , Chris Rorden [aut] , Martin J Fiedler [cph] , Cong Xu [cph] , Pascal Gloor [cph]


Documentation:   PDF Manual  


Task views: Medical Image Analysis


BSD_3_clause + file LICENCE license


Imports Rcpp, RNifti

Suggests testthat, covr

Linking to Rcpp, RNifti


Suggested by tractor.base.


See at CRAN