NAME

DESCRIPTION

We are absolutely lost in standards, versions and ACR/NEMA dialects. Here
you can only read how we handle this format. The format is written in one
file with extension ‘.ima’.
The format consists of a group of fields with different elements, in a serie
of tags. Does that explain you something? The image data is stored from left
to right and from top to bottom.
The basic defines for the format:
---------------------------------------------------------------------------
#define MDC_ACR_TAG_SIZE 8 /* size of group+element+length */
typedef struct {
Uint16 group; /* the kind of group */
Uint16 element; /* the kind of element */
Uint32 length; /* the length of data */
Uint8 *data; /* pointer to the data */
} MDC_ACR_TAG;
---------------------------------------------------------------------------
What does the format support or not support:
===========================================================================
Item Supported Not Supported
===========================================================================
Color Map : grayscale -
File Endian : little & big -
Pixeltypes : all integers (signed/unsigned) float & double
===========================================================================
Scaling factors : quantify & calibrate factors/image are NOT supported,
unless you define your own tags
---------------------------------------------------------------------------
Dimensions/Image : different dimensions for each image are supported
---------------------------------------------------------------------------
Pixeltypes/Image : different pixeltypes for each image are supported
===========================================================================
An ACR/NEMA file could look like this, in fact it is the kind we write:
===========================================================================
GROUP0x0008Identifyinginformation
===========================================================================
Uint16 Group number : 0x0008
Uint16 Element number : 0x0000 (first element of any group)
Uint32 Element length in bytes : (4)
Int32 Length of group in bytes : (X) (143)
X = [total length of this group] - [total bytes of this first tag (12)]
---------------------------------------------------------------------------
Uint16 Group number : 0x0008
Uint16 Element number : 0x0001
Uint32 Element length in bytes : (4)
Int32 Total bytes to end of file : Y
Y = [filesize] - [total bytes of first two tags]
---------------------------------------------------------------------------
Uint16 Group number : 0x0008
Uint16 Element number : 0x0010
Uint32 Element length in bytes : (12)
char * Recognition Code : (ACR-NEMA 2.0)
---------------------------------------------------------------------------
Uint16 Group number : 0x0008
Uint16 Element number : 0x0020
Uint32 Element length in bytes : (10)
char * Study Date : yyyy.mm.dd
---------------------------------------------------------------------------
Uint16 Group number : 0x0008
Uint16 Element number : 0x0030
Uint32 Element length in bytes : (14)
char * Study Time : hh.mm.ss.frac_
---------------------------------------------------------------------------
Uint16 Group number : 0x0008
Uint16 Element number : 0x0040
Uint32 Element length in bytes : (2)
Int16 Data Set Type : 0 = Images
256 = Raw data
---------------------------------------------------------------------------
Uint16 Group number : 0x0008
Uint16 Element number : 0x0060
Uint32 Element length in bytes : (2)
char * Image Modality : (NM)
---------------------------------------------------------------------------
Uint16 Group number : 0x0008
Uint16 Element number : 0x0070
Uint32 Element length in bytes : (24)
char * Manufacturer : (MedCon v?.?? - Erik Nolf)
---------------------------------------------------------------------------
Uint16 Group number : 0x0008
Uint16 Element number : 0x0080
Uint32 Element length in bytes : (11)
char * Institution ID : (UZ-GENT/RUG)
===========================================================================
GROUP0x0010PatientInformation
===========================================================================
Uint16 Group number : 0x0010
Uint16 Element number : 0x0000
Uint32 Element length in bytes : (4)
Int32 Length of group in bytes : (96)
---------------------------------------------------------------------------
Uint16 Group number : 0x0010
Uint16 Element number : 0x0010
Uint32 Element length in bytes : (35)
char * Patient Name :
---------------------------------------------------------------------------
Uint16 Group number : 0x0010
Uint16 Element number : 0x0020
Uint32 Element length in bytes : (35)
char * Patient ID :
---------------------------------------------------------------------------
Uint16 Group number : 0x0010
Uint16 Element number : 0x0040
Uint32 Element length in bytes : (2)
char * Patient Sex : M_ = male
F_ = female
O_ = others
===========================================================================
GROUP0x0018AcquisitionInformation
===========================================================================
Uint16 Group number : 0x0018
Uint16 Element number : 0x0000
Uint32 Element length in bytes : (4)
Int32 Length of group in bytes : (122)
---------------------------------------------------------------------------
Uint16 Group number : 0x0018
Uint16 Element number : 0x0030
Uint32 Element length in bytes : 32
char * Radionuclide :
---------------------------------------------------------------------------
Uint16 Group number : 0x0018
Uint16 Element number : 0x0050
Uint32 Element length in bytes : (13)
char * Slice Thickness in mm : (+0.000000e+00)
---------------------------------------------------------------------------
Uint16 Group number : 0x0018
Uint16 Element number : 0x0088
Uint32 Element length in bytes : (13)
char * Slice Spacing in mm : (+0.000000e+00)
---------------------------------------------------------------------------
Uint16 Group number : 0x0018
Uint16 Element number : 0x1120
Uint32 Element length in bytes : (13)
float Gantry Tilt in degrees : (+0.000000e+00)
---------------------------------------------------------------------------
Uint16 Group number : 0x0018
Uint16 Element number : 0x1160
Uint32 Element length in bytes : (32)
char * Filter Type :
---------------------------------------------------------------------------
Uint16 Group number : 0x0018
Uint16 Element number : 0x5100
Uint32 Element length in bytes : (32)
char * Patient Position : (supine)
supine = face-up on the table
prone = face-down towards the table
other?
===========================================================================
GROUP0x0020RelationshipInformation
===========================================================================
Uint16 Group number : 0x0020
Uint16 Element number : 0x0000
Uint32 Element length in bytes : (4)
Int32 Length of group in bytes : (352)
---------------------------------------------------------------------------
Uint16 Group number : 0x0020
Uint16 Element number : 0x0010
Uint32 Element length in bytes : (10)
char * Study ID :
---------------------------------------------------------------------------
Uint16 Group number : 0x0020
Uint16 Element number : 0x0013
Uint32 Element length in bytes : (6)
char * Image Number :
---------------------------------------------------------------------------
Uint16 Group number : 0x0020
Uint16 Element number : 0x0020
Uint32 Element length in bytes : (32)
char * Patient Orientation : (L\P)
(direction of image row in patient\direction of image column in patient)
’L’ = Left (hand) ’A’ = Anterior (to front) ’H’ = Head
’R’ = Right (hand) ’P’ = Posterior (to back) ’F’ = Feet
---------------------------------------------------------------------------
Uint16 Group number : 0x0020
Uint16 Element number : 0x0030
Uint32 Element length in bytes : (41)
char * Image Position in mm :
* * * * * * * * * * * * *
Gives the 3D equipment based coordinates of the upper left hand corner
in the image. Example: (+0.000000e+00\+0.000000e+00\+0.000000e+00)
=X-axis =Y-axis =Z-axis
"When facing the front of the gantry (equipment device), and with the
gantry in a neutral (untilted) position, the x-axis is increasing to the
right; the y-axis is increasing down (gravitational attraction); and the
z-axis is defined as the line orthogonal to x and y, with increasing
values from the front to the back of the gantry."
(From a Papyrus 2.3 document: UIN/HCUG 1990, 91)
My note: where is its origin? For our ECAT images we choose the origin
in the right/back/down point of the gantry
A
______H
|\______\F Looking to the scanner, this is a representation of the
R |.|.... | L volume our scanner detects. My origin is in the point we
\|_____| can’t see ;-) Our images are transversal slices, beginning
at the head towards the feet (so patient orientation = L\P)
P and the patient position is supine.
Therefore, the coordinates of the first pixel in our images is:
Image 0:
-(PIXEL_X_SIZE*PIXELS_IN_X);-(PIXEL_Y_SIZE*PIXELS_IN_Y);-0
Image 1:
-(PIXEL_X_SIZE*PIXELS_IN_X);-(PIXEL_Y_SIZE*PIXELS_IN_Y);-(SLICE_WIDTH*1)
Image n:
-(PIXEL_X_SIZE*PIXELS_IN_X);-(PIXEL_Y_SIZE*PIXELS_IN_Y);-(SLICE_WIDTH*N)
| |
image width image height
A view of the coordinate system you can see in 0x0020;0x0035.
However, it could all be wrong too! By the way, for DICOM it’s retired stuff.
* * * * * * * * * * * * *
---------------------------------------------------------------------------
Uint16 Group number : 0x0020
Uint16 Element number : 0x0032
Uint32 Element length in bytes : (41)
char * Image Position (Patient) in mm:
* * * * * * * * * * * * *
The same as above but know based on the coordinate system of the patient.
A DICOM replacement for the above values:
"The direction of the axes is defined fully by the patient’s orientation.
The x-axis is increasing to the left hand side of the patient. The y-axis
is increasing to the posterior side of the patient. The z-axis is increasing
toward the head of the patient.
The patient based coordinate system is a right handed system, i.e. the vector
cross product of a unit vector along the positive x-axis and a unit vector
along the positive y-axis is equal to a unit vector along the positive z-axis.
NOTE: If a patient lies parallel to the ground, face-up on the table, with
his feet-to-head direction the same as front-to-back direction of the
imaging equipment, the direction of the axes of the patient based
coordinate system and equipment based coordinate system in previous
versions of the DICOM Standard will coincide"
(From the NEMA Standards Publication PS3.3(199X)
This means that the coordinate systems are equal when a patient lies on his
back (supine) with his head first in the scanning equipment. This is suposed
as the default condition for our ECAT scans ...
For our ECAT files, the values will be the same as for 0x0020;0x0030. At least
if the doctors don’t plan to lie the patient differently ;-) Then we ’ll have
to write some extra code, isn’t it?
* * * * * * * * * * * * *
---------------------------------------------------------------------------
Uint16 Group number : 0x0020
Uint16 Element number : 0x0032
Uint32 Element length in bytes : (83)
char * Image Orientation :
* * * * * * * * * * * * *
Based on 0x0020;0x0030 these are the direction cosines of a unit vector
on the first row and on the first column based on the equipment coordinate
system (or our patient coordinate system, because they coincide as we
described above).
(to back of the scanner)
+Z (or head of the patient)
\
\ coordinate system
\
\_ _ _ _ _ _ _ +X (to right of the scanner)
| (or left of the patient)
|
|
|
+Y (to the ground)
(or back of the patient)
* * * * * * * * * * * * *
Remember we take transversal slices (Right to Left of patient, Anterior to
Posterior) while the patient lies on his back with his head first in gantry.
Then our images lie in the plane XY and the unit vectors are
upper left
corner of image (X)
+ - - - - > (x1,y1,z1 = 1,0,0)
| unit vector on row
|
|
(Y) V (x2,y2,z2 = 0,1,0)
unit vector on column
In this case: a) in point (x1,y1,z1)
X direction cosinus = +1
Y direction cosinus = -0
Z direction cosinus = -0
b) in point (x2,y2,z2)
X direction cosinus = +0
Y direction cosinus = +1
Z direction cosinus = +0
How about the signs and values?
cos(0 or 360) = +1
cos(90) = +0
cos(180) = -1
cos(270) = -0
The angle between an axis and the vector, you determine with a so called
"corkscrew-rule": You must turn from THE AXIS towards THE VECTOR (=angle)
the same direction so a corkscrew should proceed in the direction
of an axis orthogonal on the plane formed by THE AXIS and THE VECTOR.
Well, thats what it should be I think. If your images are tilted, it
will be a bit harder, isn’t it?
For our ECAT images an example value will be:
(+1.000000e+00\-0.000000e+00\+0.000000e+00\
+0.000000e+00\+1.000000e+00\-0.000000e+00)
Again, this tag is retired for DICOM ...
* * * * * * * * * * * * *
---------------------------------------------------------------------------
Uint16 Group number : 0x0020
Uint16 Element number : 0x0037
Uint32 Element length in bytes : (83)
char * Image Orientation Patient :
The same as for tag 0x0020;0x0032 but now considered for the patient
coordinate system ...
===========================================================================
GROUP0x0028ImagePresentation
===========================================================================
Uint16 Group number : 0x0028
Uint16 Element number : 0x0000
Uint32 Element length in bytes : (4)
Int32 Length of group in bytes : (127)
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0005
Uint32 Element length in bytes : (2)
Int16 Image Dimensions : (2)
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0010
Uint32 Element length in bytes : (2)
Int16 Rows :
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0011
Uint32 Element length in bytes : (2)
Int16 Columns :
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0030
Uint32 Element length in bytes : (27)
char * Pixel Size in mm : (+0.000000e+00\+0.000000e+00)
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0060
Uint32 Element length in bytes : (4)
char * Compression code : (NONE)
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0100
Uint32 Element length in bytes : (2)
Int16 Bits Allocated :
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0101
Uint32 Element length in bytes : (2)
Int16 Bits per Pixel :
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0102
Uint32 Element length in bytes : (2)
Int16 High Bit :
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0103
Uint32 Element length in bytes : (2)
Int16 Pixel Representation : 0 = unsigned
1 = signed
---------------------------------------------------------------------------
Uint16 Group number : 0x0028
Uint16 Element number : 0x0200
Uint32 Element length in bytes : (2)
Int16 Image Location : (7fe0)
===========================================================================
GROUP0x7fe0PixelInformation
===========================================================================
Uint16 Group number : 0x7fe0
Uint16 Element number : 0x0000
Uint32 Element length in bytes : (4)
Int32 Length of group in bytes : Z
Z = [imagesize] + 8
---------------------------------------------------------------------------
Uint16 Group number : 0x7fe0
Uint16 Element number : 0x0010
Uint32 Element length in bytes : (imagesize)
Uint8 * Image Data :
---------------------------------------------------------------------------
This was an example of an ACR/NEMA file holding one image, as normal
ACR/NEMA files do. However, as we are interested in multiple images, we use
an ACR/NEMA dialect such as Papyrus. In this case we sequentially
concatenate different ACR/NEMA files into one single large file!

NOTES

Because of the previous remark, we must notify that in the Element 0x0001 of
Group 0x0008, the [filesize] means the filesize in case of this one ACR/NEMA
file and NOT the real filesize!
For the Group 0x0028, Element 0x0100: ‘Bits Allocated’
We only support a multiple of 8.
For the Group 0x0028, Element 0x0102: ‘High Bit’
We only support ‘High Bit’ = [‘Bits per Pixel’] - 1,
so we only accept images stored in the file endian type.