The format of any image file is composed of two parts: the header of the parameter and the pixel data ).
The headers in BMP, JPEG, And Tiff formats only describe the basic parameters of the image, such as the number of rows and columns, the number of digits used for each vertex, whether the image is compressed, and the color palette. Headers are usually fixed in length.
Medical Imaging also requires many other parameters, such as basic patient data, basic exam data, series data, and location data. In addition, each modality is different from the content required by each image. Therefore, the general image format cannot be used.
1. four levels of DICOM content
1. Patient (patient)
2. Study (test)
3. Series)
4. Image)
Although the content of the first few layers is the same in many images, they must be included in each image file.
Each layer is called an Information Entity or IE (referenced from the relational database schema design ). Each layer is subdivided into modules. The smallest unit in each module is an attribute or element.
For example: CR image (DICOM part 3, a.2.3, table A.2-1
1. Patient ie:
A. Patient module (refer to c.7.1.1)
2. Study ie:
A. Study Module (refer to c.7.2.1)
B. Patient Study Module (refer to c.7.2.2)
3. Series ie:
A. General series (see c.7.3.1)
B. Cr series (see c.8.1. 1)
C. General equipment (see c.7.5.1)
4. Image ie:
A. genrral image (c.7.6.1)
B. image pixel (c.7.6.3)
C. Contrast/bolus (c.7.6.4)
D. CR image (c.8.1.2)
...
I. SOP common (C.12.1)
Find all elements in these modules (tables) and create a CR image architecture.
Note that some of these modules are mandatory (modatory) and some are selected by users ). In each module, the attribute/element table contains five types: Type 1, 1C, 2, 2c, and 3. Type 1 is required, and 2 is required, but the content can be empty. Type 3 is optional. Therefore, there are not many elements in a CR image. After the tables are expanded, these elements form a dataset.
What is the format of writing to a file or transmitting it over the network? This depends on Part 5. The structure of an element is:
1. Group Tag: 16-bit
2. Element Tag: 16-bit
3. Length (or VR/length): 32-bit
4. Data (bytes of length)
Each element DICOM Standard Part 6 that is used defines a group tag and an element tag. For example:
Patient Name: 0x0010, 0x0010
Patient ID: 0x0010, 0x0020
...
VR refers to the element format. For example, the VR of patinet name Is PN. The format is last_name ^ first_name ^ middle_name ^ prefix ^ surfix. My English name is: Wang ^ JB ^ dr. ^
When writing data out, you need to do the following:
1. Sort all elements by group tage and element tag (SORT ). From small to large.
2. If the DICOM file is written into DICOM media, first write 128 bytes preamble (usually blank), add "dicm", and add group 2 meta header. (Let's Talk About Part 10)
3. If the dataset contains sequence elements, each item in the sequence is a dataset.
With this knowledge, you can start to write a small Conversion Program from BMP to DICOM. Key materials:
Modality (0008,006 0): SC
Photometric interpretation (4, 0028,000): RGB
Sop class uid: 1.2.840.10008.1.5.4.1.1.7
The simplest way is to write a structure and then an array.
Typedef struct dicomelem
{
Short int group_tag,
Short int element_tag,
Char VR [4],
Int length,
Char data [128]
} Dicomelem;
Dicomelem crdataset [] =
{
{0x0008, 0x0005, "CS", 10, "iso_ir 100 "},
{0x0008, 0x0008, "CS", 16, "original \ primary "},
...
{0x0010, 0x0010, "PN", 16, "My ^ test ^ image ^ "},
{0x0010, 0x0020, "sh", 6, "123456 "},
...
{0, 0, "", 0 ,""}
};
Void writecdimage (File * FP)
{
Dicomelem ELEM = crdataset [0];
Unsigned long int lcombotag;
Int ncols, nrows;
Unsigned char * ppixeldata
Unsigned long int lpixellength;
Ppixeldata = loadbmp imgedata ("myimage.bmp", ncols, nrows, lpixellength );
While (crdataset [I]. group_tag)
{
Lcombotag = (crdataset [I]. group_tag <16) | crdataset [I]. element_tag;
Tch (lcombotag)
{
Case 0x00280010:
* (Short int *) crdataset [I]. Data) = ncols;
Break;
Case 0x00280011:
* (Short int *) crdataset [I]. Data) = nrows;
Break;
...
}
// Write group and element tag
Fwrite (& lcombotag, 1, sizeof (long), FP );
// Write Vr
Fwrite (crdataset [I]. VR, 1, 2, FP );
If (lcombotag! = 0x7fe00010)
{
Fwrite (crdataset [I]. length, 1, sizeof (short), FP );
Fwrite (crdataset [I]. Data, 1, crdataset. length, FP );
}
Else
{
Fwrite ("\ 0 \ 0", 1, 2, FP); // two blank bytes after Vr
Fwrite (& lpixellength, 1, sizeof (long), FP); // Length
Fwrite (ppixeldata, 1, lpixellength, FP );
}
I ++;
}
}
Unsigned char * loadbmp imgedata (char * filename, Int & ncols, Int & nrows, unsigned long & lpixellength)
{
....
}
Write the details by yourself.
2. The most difficult thing to read and write DICOM files is
DICOM Sequence
DICOM pixel data
The analogy of sequence in C is a structure array, which is a structure set structure, so it is difficult to read. What's more troublesome is that sequence can also not define the length, that is, the length is-1. You need to find (fffe, e0dd) to determine whether the sequence ends.
Each structure in array is an item in DICOM sequence. An item starts with a specific element (fffe, e000 ). If the length of an item is-1, the end of the item is determined by finding (fffe, e00d.
Pixel data (7fe0, 0010) is a special DICOM element. Always at the end of all elements. It has two similarities with sequence: The length zone is always 32-bit (that is, in the case of explicit VR, you need to fill in two bytes after the VR area, and then add the length of 4-bytes.
Such as compression, each graph is saved with an item. The first item is an offset table. The offset of each graph is a DWORD (4 bytes), and the offset of the first graph is 0.
Iii. DICOM file details
The Data Length of element must be an even number.
Note the differences between big endian and little endian. The software must automatically determine the machine's endian and DICOM file's transfer syntax. Generally, Intel PC is little endian and sun is big endian.
If the machine's endian and Data's endian are not correct, use byte swap. Perform binary data related to all the root numbers of byte swap, that is, Vr = SS, US, SL, UL, FL, FD, ow, at, and so on. DICOM group tag and element tag must also be two byte swap. Item refers to the item of DICOM sequence.
0x7fe0, 0x0010, "ob", ''', 0 xffffffff // tag, VR, Length
0 x fffe, 0x0000, 0 xffffffff // offset item begins
0x00000000 // offset of first image = 0
0x00001000 // offset of second image = 4096 (for example)
...
0 xfffe, 0xe00d // end of offset item
0 xfffe, 0x0000, 0x00001000 // first image item and length = 4096 (for example)
... // (4096 bytes)
0 xfffe, 0xe00d // end of first image
...
0 xfffe, 0xe0dd // end o of pixel data sequence