-
Notifications
You must be signed in to change notification settings - Fork 0
/
feed.xml
251 lines (211 loc) · 22.9 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.5">Jekyll</generator><link href="blog.flavioschuindt.com/feed.xml" rel="self" type="application/atom+xml" /><link href="blog.flavioschuindt.com/" rel="alternate" type="text/html" /><updated>2019-12-30T13:49:02-08:00</updated><id>blog.flavioschuindt.com/feed.xml</id><title type="html">Flávio Schuindt</title><subtitle>All content copyright Flávio Schuindt © 2019. All rights reserved.</subtitle><entry><title type="html">Into the DICOM World - Part 1</title><link href="blog.flavioschuindt.com/healthcare/dicom/2019/12/30/into-the-dicom-world-part-1.html" rel="alternate" type="text/html" title="Into the DICOM World - Part 1" /><published>2019-12-30T01:15:00-08:00</published><updated>2019-12-30T01:15:00-08:00</updated><id>blog.flavioschuindt.com/healthcare/dicom/2019/12/30/into-the-dicom-world-part-1</id><content type="html" xml:base="blog.flavioschuindt.com/healthcare/dicom/2019/12/30/into-the-dicom-world-part-1.html"><p style="text-align: justify">This is the first post in a series of four presenting the DICOM standard. We’ll cover the basic understandind of DICOM, starting with the DICOM data encoding. The next posts will focus on the DICOM Object, the DICOM Image representation and DICOM Communication Model.</p>
<h2 id="introduction">Introduction</h2>
<p style="text-align: justify"><a href="https://www.dicomstandard.org/">DICOM</a> stands for <span style="color:red;font-weight:bold">D</span>igital <span style="color:red;font-weight:bold">I</span>maging and <span style="color:red;font-weight:bold">Co</span>mmunications in <span style="color:red;font-weight:bold">M</span>edicine and is the <strong>international standard</strong> to transmit, store, retrieve, print, process, and display <strong>medical imaging</strong> information. It’s the standard behing radiology equipment, networking servers and the <strong>P</strong>icture <strong>A</strong>rchiving and <strong>C</strong>ommunication <strong>S</strong>ystem (PACS).</p>
<p style="text-align: justify">You can think about it in this way: You have different entities (image-acquisition devices, PACS, workstations, etc.) playing different roles in the Healthcare world and DICOM is the standard that allows these entities to exchange information, i.e., interoperability.</p>
<p><img src="/assets/images/dicom_logo.jpg" alt="alt text" title="DICOM Logo" /></p>
<h2 id="the-history">The History</h2>
<p style="text-align: justify">In the beginning of the 80’s, it was almost impossible for anyone other than manufacturers of CT and MRI devices to read and decode the images produced by the device. In <strong>1983</strong> the <a href="https://www.acr.org/">American College of Radiology</a> and the <a href="https://www.nema.org/pages/default.aspx">National Electrical Manufacturers Association</a> worked together and estabilished a standards committee to meets the combined needs of radiologists, physicists and equipment vendors. Then, in <strong>1985</strong> the first version of DICOM was released with name <strong>ACR-NEMA 300</strong>. The second version of the ACR-NEMA 300 came out in <strong>1988</strong> and gained increased acceptance among vendors. Only in <strong>1993</strong> the third version came out and was finally named as <strong>DICOM</strong>. The name changed because the Cardiologists entered in the game too and a name which contains only radiologists (ACR) would not make the cardiologists happy. There was a war a that time. The DICOM 3.0 from <strong>1993</strong> had <strong>9</strong> parts of the standard and the current version, <strong>which is still 3.0</strong>, incorporated <strong>10</strong> new parts and <strong>210</strong> supplements.</p>
<h2 id="dicom-data-types-vrs">DICOM Data Types: VRs</h2>
<p style="text-align: justify">Each DICOM element has a <strong>V</strong>alue <strong>R</strong>epresentation (<strong>VR</strong>), i.e., the type of values that one can assign to it. Think about it as the same variable declaration that you do in a programming language: you say the <code class="highlighter-rouge">name</code> and the <code class="highlighter-rouge">type</code> of the variable. DICOM defines 27 basic data types and any data that you intend to encode in DICOM <strong>must</strong> use one of these 27 data types. You can see all of them <a href="http://dicom.nema.org/medical/dicom/current/output/chtml/part05/PS3.5.html">here</a>.</p>
<p>For example, following our analogy with programming languages, let’s say you would like to represent the number of rows of a medical image in C:</p>
<p><code class="highlighter-rouge">unsigned short rows = 800;</code></p>
<p>And the same data in DICOM:</p>
<p><code class="highlighter-rouge">Tag (0028,0010) = 800;</code></p>
<p><code class="highlighter-rouge">(0028,0010)</code> is the DICOM tag for the image rows.</p>
<p style="text-align: justify">I’m not going to enter in the details here of each and every VR. For this you can always refer to the PS3.5 of the DICOM standard mentioned above. However, there are general rules that apply for all VRs that you should be aware of:</p>
<ul style="text-align: justify">
<li>The data can be in text or binary format. Each VR will define if its store text or binary;</li>
<li>Every VR has a data length. This is exactly the way DICOM knows where each data element starts and ends;</li>
<li>A VR can have a fixed data length or not for the number of characters/bytes. For example: <strong>DA</strong>, Date, has a fixed length of 8, a string in the format <strong>YYYYMMDD</strong>. On the other hand, <strong>DS</strong>, Decimal string, for example, has a length of 16 maximum;</li>
<li>In the process of encondig, no matter if fixed length or not, all DICOM elements <strong>must contain even length</strong>, i.e., if text, DICOM will guarantee an even number of characters and, if binary, DICOM will guarantee an even number of bytes. It adds a blank space if text data or a <strong>NULL</strong> byte if the number of characters or bytes are odd, respectively.</li>
</ul>
<p style="text-align: justify">Ok, now you know that VR is the basic foundation that define all the available data type available in DICOM. What is missing now? If you pay attention, the VR is only defining the data type, but we need a way to define <strong>data elements</strong> and it should be consistent among different DICOM vendors. Then comes the <strong>DICOM Dictionary</strong>.</p>
<h2 id="dicom-data-dictionary">DICOM Data Dictionary</h2>
<p style="text-align: justify">The <a href="http://dicom.nema.org/medical/dicom/current/output/html/part06.html">DICOM Data Dictionary</a> is in its essence a big table that specifies all data elements alongside with their properties. See for example a DICOM dictionary example available in the awesome book <a href="https://www.amazon.com/Digital-Imaging-Communications-Medicine-DICOM/dp/3642108490">Digital Imaging and Communications in Medicine (DICOM): A Practical Introduction and Survival Guide</a>:
<img src="/assets/images/dicom_dict.png" alt="alt text" title="DICOM Dictionary" />
From this table, you probably already noted that each element belongs to a group. Therefore, a pair <code class="highlighter-rouge">(group, element)</code> uniquely identifies an element in DICOM and it’s known as a <strong>DICOM Tag</strong>. Other properties are the <strong>name</strong>, <strong>keyword</strong>, <strong>VR</strong>, <strong>VM</strong> and <strong>RET</strong>. While DICOM applications refer to each data element by its group and element, <strong>name</strong> is a more human-readable description of the data element. The <strong>keyword</strong> is a one-word text that provide a full description of the data element. Think about it as a represenation more close to property names in standards like XML or HTTP. <strong>VR</strong> is the Value Represenation discussed in the previous section. <strong>VM</strong> is the quantity of values that you can store in this data element. For example, if you have a <strong>VM</strong> of 1 you can only store one data of that specificy <strong>VR</strong>. On the other hand, a <strong>VM</strong> of <strong>1-n</strong> would allow one or more values of the specific <strong>VR</strong>. One important thing to note here is to understand how DICOM store multiple values into a single element? For binary data, DICOM uses the legth of the single-value VR and just apply an offset to read the next element:</p>
<p><img src="/assets/images/multi_values_dicom.png" alt="alt text" title="Multi-value DICOM binary data" /></p>
<p style="text-align: justify">For text data, there are no fixed legth. In this case, DICOM uses backslash (<strong>\</strong>) as a delimiter. The data element (0010,1000), for example, <strong>Other Patient IDs</strong>, has VR <strong>LO</strong> (Long Sting) and multiplicity 1-n. In this case you could represent a patient who has, let’s say, three patient IDs (123, 456 and 789) in this way: <strong>“123\456\789”</strong>.</p>
<p style="text-align: justify">Last, but not least, the <strong>RET</strong> in the dicom dictonary defines a data element as RETIRED. As an analogy, they are like the <strong>deprecated</strong> objects and/or methods in a programming language.</p>
<p style="text-align: justify">Another type of DICOM Dictonary is the <strong>Private DICOM Dictionary</strong>. As you can see in the previous section, the public DICOM Dictionary is composed of more than 2000 data elements. While this looks impressive, allowing you to encode almost every information you need, sometimes you need to define custom attributes that only you, as a manufacturer, know. DICOM is prepared for it and reserves all odd groups for private data elements. For the sake of example, you could define <strong>(0009, 1010)</strong> as Patient’s Education Level. Then, if you need that a specific consumer understand this data, you need to distribute this private dictionary so the consumer can understand each tag that you define.</p>
<h2 id="dicom-data-encoding">DICOM Data Encoding</h2>
<p style="text-align: justify">We now have the entire foundation to encode an object in DICOM. And this is very simple: A DICOM object is just a set of DICOM data elements together. Each data element, as described before, is mainly describe by a tag. See for example a real DICOM object read by the Free DICOM Medical Image Viewer <a href="https://horosproject.org/">Horos</a>:
<img src="/assets/images/dicom_object.png" alt="alt text" title="DICOM Object" /></p>
<p style="text-align: justify">The picture is easy for a human to read it, i.e., you just need to go in every data element and read the value. However, we need to <strong>encode</strong> it properly, so digital systems can store, read and transmit all of this DICOM information properly. Part PS3.5 of the DICOM standard defines two encoding types: <strong>implicit VR</strong> and <strong>explicit VR</strong>. The difference between them is that the former doesn’t have specific bytes to define the type of the VR while the later reserves two bytes to encode the VR. Another important point is that explicit VR is important for encoding nonstandard (proprietary) VRs that you can’t find in the standard DICOM dictionary.</p>
<p><strong>Implicit VR</strong>:</p>
<table>
<thead>
<tr>
<th><span style="color:red;font-weight:bold">Group Number</span></th>
<th><span style="color:green;font-weight:bold">Element Number</span></th>
<th><span style="color:blue;font-weight:bold">Value Length</span></th>
<th><span style="color:orange;font-weight:bold">Value</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>2 bytes</td>
<td>2 bytes</td>
<td>4 bytes X</td>
<td>X (must be even)</td>
</tr>
</tbody>
</table>
<p><br /></p>
<p><strong>Explicit VR</strong>:</p>
<table>
<thead>
<tr>
<th><span style="color:red;font-weight:bold">Group Number</span></th>
<th><span style="color:green;font-weight:bold">Element Number</span></th>
<th><span style="color:magenta;font-weight:bold">VR</span></th>
<th><span style="color:blue;font-weight:bold">Value Length</span></th>
<th><span style="color:orange;font-weight:bold">Value</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>2 bytes</td>
<td>2 bytes</td>
<td>2 bytes</td>
<td>2 bytes X</td>
<td>X (must be even)</td>
</tr>
</tbody>
</table>
<p><br /></p>
<p style="text-align: justify">Let’s see an example starting with the Implicit VR. Let’s say that we are trying to encode the data element <strong>SeriesDescription</strong> from the picture whose value is “<em>Chest pa</em>”. The encoding would be:</p>
<table>
<thead>
<tr>
<th><strong>Byte #</strong></th>
<th>0</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>10</th>
<th>11</th>
<th>12</th>
<th>13</th>
<th>14</th>
<th>15</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Decimal</strong></td>
<td>8</td>
<td>0</td>
<td>62</td>
<td>16</td>
<td>8</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>C</td>
<td>h</td>
<td>e</td>
<td>s</td>
<td>t</td>
<td> </td>
<td>p</td>
<td>a</td>
</tr>
<tr>
<td><strong>Binary</strong></td>
<td><span style="color:red;font-weight:bold">08</span></td>
<td><span style="color:red;font-weight:bold">00</span></td>
<td><span style="color:green;font-weight:bold">3E</span></td>
<td><span style="color:green;font-weight:bold">10</span></td>
<td><span style="color:blue;font-weight:bold">08</span></td>
<td><span style="color:blue;font-weight:bold">00</span></td>
<td><span style="color:blue;font-weight:bold">00</span></td>
<td><span style="color:blue;font-weight:bold">00</span></td>
<td><span style="color:orange;font-weight:bold">43</span></td>
<td><span style="color:orange;font-weight:bold">68</span></td>
<td><span style="color:orange;font-weight:bold">65</span></td>
<td><span style="color:orange;font-weight:bold">73</span></td>
<td><span style="color:orange;font-weight:bold">74</span></td>
<td><span style="color:orange;font-weight:bold">20</span></td>
<td><span style="color:orange;font-weight:bold">70</span></td>
<td><span style="color:orange;font-weight:bold">61</span></td>
</tr>
</tbody>
</table>
<p><br /></p>
<p style="text-align: justify">Note that the default Endian type for DICOM is Little Endian, so for multi-byte numbers like Group Number, Element Number and Value Length, the lowest (rightmost) byte comes first and the highest byte is the next. Also, note that, as discussed earlier, DICOM always guarantee that the VR length is even, i.e., the number <strong>X</strong> will always be even. In case of text value, a space will be added and in case of binary value a <strong>NULL</strong> byte termiantor will be added.</p>
<p style="text-align: justify">Did you realize now how easy is for DICOM to parse it? In the above example, it reads the first two bytes and it knows that it’s the <strong>Group Number</strong>. Next two bytes and it’s the <strong>Element Number</strong>. In the sequence, it reads 4 bytes (call it <strong>X</strong>) that tells the <strong>Value Length</strong> of the actual content. Last, but not least, it reads X bytes to retrieve the actual <strong>Value</strong>.</p>
<p>The same encoding with the explicit VR would be:</p>
<table>
<thead>
<tr>
<th>Byte #</th>
<th>0</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>10</th>
<th>11</th>
<th>12</th>
<th>13</th>
<th>14</th>
<th>15</th>
</tr>
</thead>
<tbody>
<tr>
<td>Decimal</td>
<td>8</td>
<td>0</td>
<td>62</td>
<td>16</td>
<td>L</td>
<td>O</td>
<td>8</td>
<td>0</td>
<td>C</td>
<td>h</td>
<td>e</td>
<td>s</td>
<td>t</td>
<td> </td>
<td>p</td>
<td>a</td>
</tr>
<tr>
<td>Binary</td>
<td><span style="color:red;font-weight:bold">08</span></td>
<td><span style="color:red;font-weight:bold">00</span></td>
<td><span style="color:green;font-weight:bold">3E</span></td>
<td><span style="color:green;font-weight:bold">10</span></td>
<td><span style="color:magenta;font-weight:bold">4C</span></td>
<td><span style="color:magenta;font-weight:bold">4F</span></td>
<td><span style="color:blue;font-weight:bold">08</span></td>
<td><span style="color:blue;font-weight:bold">00</span></td>
<td><span style="color:orange;font-weight:bold">43</span></td>
<td><span style="color:orange;font-weight:bold">68</span></td>
<td><span style="color:orange;font-weight:bold">65</span></td>
<td><span style="color:orange;font-weight:bold">73</span></td>
<td><span style="color:orange;font-weight:bold">74</span></td>
<td><span style="color:orange;font-weight:bold">20</span></td>
<td><span style="color:orange;font-weight:bold">70</span></td>
<td><span style="color:orange;font-weight:bold">61</span></td>
</tr>
</tbody>
</table>
<p><br /></p>
<p style="text-align: justify">You can see that for explicit encondig the 4 bytes of the VR field is divided in two fields of two bytes each, containing <strong>explicitely</strong> the VR type.</p>
<h2 id="conclusion">Conclusion</h2>
<p style="text-align: justify">In this first post, we covered the basics of DICOM and learned how to describe the basic data elements in DICOM. The next post will talk about the DICOM objects.</p></content><author><name></name></author><category term="DICOM" /><category term="Healthcare" /><summary type="html">This is the first post in a series of four presenting the DICOM standard. We’ll cover the basic understandind of DICOM, starting with the DICOM data encoding. The next posts will focus on the DICOM Object, the DICOM Image representation and DICOM Communication Model.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="blog.flavioschuindt.com/assets/images/dicom_logo_preview.png" /></entry></feed>