[Insight-users] Create 3D image data by a series of 2D dicom files

Jolinda Smith jolinda at darkwing . uoregon . edu
Tue, 2 Sep 2003 12:30:44 -0700


Hi Chunyan,

If it's acceptable to you to write MetaImage headers for your data, you
can use MRIConvert (http://lcni . uoregon . edu/~jolinda/MRIConvert). That's
the easiest way. As far as ordering the images...I can tell you the most
reliable way to order them, but I don't know how to read DICOM tags
using the ITK DICOM reader class. You may want to read the files using
another library (such as DCMTK) and then pass the image data to ITK.

Assuming that you've found a way to read the tags, the only reliable way
to order the slices is to use the "Image Orientation Patient" and "Image
Position Patient" tags. However, if you're only reading in fairly
ordinary sequences from a single source, you can probably use the "Image
Number" tag to order the slice. I've included the text of an email I
sent to Mathieu Malaterre that discusses the subject. Incidentally, Dave
Clunie of comp.protocols.dicom deserves credit for pointing out that
this is the only reliable method of ordering slices. (We'll ignore
sequences that produce multiple images at each slice location for now.)

---------------------

That's the easiest thing [using the image number tag], but there are
still some good reasons for using the "IOP" and "IPP" information. For
one, those tags always use the same coordinate system, where "x" is left
to right, "y" is posterior to anterior, and "z" is foot to head (RAH).
The image number (aka "instance number") can depend on the scanner and
its software: before we upgraded to syngo, our scanner increased the
numbering from the top of the head to the bottom. Also, the image number
may change depending on the sequence -- for 2d sequences, it may be the
acquisition order, which could be ascending, descending, interleaved, or
even some random order. In fact, I believe you for our scanner you can
change the image numbering from the console, so it's not at all
reliable. It's also best to use those fields for the slice spacing. The
DICOM tag "Slice Spacing" is supposed to be the center-to-center
distance between adjacent slices, but on our scanner alone I've seen it
mean center-to-center slice distance, the gap between slices, and the
gap between "slabs". (These sorts of things always seem to be worse on
Siemens machines.)

The DICOM standard is online at http://medical . nema . org/ .  Most of the
tags are listed in part 6: Data Dictionary, with more information for
specific tags in part 3: Information Object Definitions. The "Image
Orientation Patient" tag gives the direction cosines for the rows and
columns for the three axes defined above. Your typical axial slices will
have a value 1/0/0/0/1/0: rows increase from left to right, columns
increase from posterior to anterior. This is your everyday "looking up
from the bottom of the head with the eyeballs up" image.

In your images, IOP =
0.999794\0.000000\-0.020289\-0.020127\-0.126071\-0.991817. So this is a
slightly-rotated coronal acquisition: rows increase from left to right,
and columns increase from head to foot.

The "Image Position Patient" tag gives the coordinates of the first
voxel in the image in the "RAH" coordinate system, relative to some
origin. On our scanner it's the magnet isocenter, but I don't know if
that's always true.

The steps I take when reconstructing a volume are these: First,
calculate the slice normal from IOP:

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];

You only have to do this once for all slices in the volume. Next, for
each slice, calculate the distance along the slice normal using the IPP
tag ("dist" is initialized to zero before reading the first slice) :

for (int i = 0; i < 3; ++i) dist += normal[i]*ipp[i];

Then I order the slices according to the value "dist". Finally, once
I've read in all the slices, I calculate the z-spacing as the difference
between the "dist" values for the first two slices.

Sorry for the long-winded answer! It may seem like a lot of trouble, but
it works really well.

Jolinda Smith
Lewis Center for NeuroImaging
University of Oregon
jolinda at uoregon . edu

----- Original Message ----- 
From: "jiang" <jiang at TI . Uni-Trier . DE>
To: "ITK" <insight-users at itk . org>
Sent: Monday, September 01, 2003 2:40 AM
Subject: [Insight-users] Create 3D image data by a series of 2D dicom
files


> Hi,
> I have tried many time to use itkDICOMImageSeriesTest.cxx to create 3d
image
> data by a series of 2d dicom files. However, neither the ITK example
nor my
> code derived from example can work. I have to give it up.
> Now I want to read the series files one by one, then generate the 3d
image
> data. How can I transfer a number of "typedef itk::Image< unsigned
short, 2
> > ImageType;" objects to one "typedef itk::Image< unsigned short ,3>
> ImageNDType" object?
> By the way, the position information of the dicom image is inside the
dicom
> header. How can I get it in order to sort the series images in right
order?
>
> Thanks a lot!
>
> Chunyan
>
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk . org
> http://www . itk . org/mailman/listinfo/insight-users
>