Mercurial > hg > orthanc-book
annotate Sphinx/source/dicom-guide.rst @ 537:2c8f4eca3cd2
fix toctree
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 05 Nov 2020 07:36:18 +0100 |
parents | 50bdd7c7e9b9 |
children | 4f3a6145ae34 |
rev | line source |
---|---|
0 | 1 .. _dicom-guide: |
2 | |
3 Understanding DICOM with Orthanc | |
4 ================================ | |
5 | |
6 .. contents:: | |
7 | |
8 | |
9 This section of the Orthanc Book provides a **gentle, informal, | |
358
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
10 high-level introduction to DICOM**. We will try and map DICOM's own |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
11 concepts to a modern terminology that should hopefully be more easy to |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
12 understand for software engineers diving for the first time into |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
13 DICOM. Once the concepts of this page are understood, interested |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
14 readers are invited to read a more formal textbook about DICOM, such |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
15 as the so-called "`Practical introduction and survival guide |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
16 <https://www.springer.com/us/book/9783642108495>`__", or to read the |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
17 full `DICOM specification |
25 | 18 <http://dicom.nema.org/medical/dicom/current/output/html/>`__. |
0 | 19 |
20 All the DICOM concepts that are defined in this introduction are | |
358
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
21 illustrated with `Orthanc <https://www.orthanc-server.com/>`__, a |
0 | 22 lightweight, yet powerful standalone DICOM server for healthcare and |
23 medical research. As Orthanc is free and open-source software, it is a | |
24 good companion to learn DICOM. | |
25 | |
26 | |
27 .. _dicom-format: | |
28 | |
29 DICOM file format | |
30 ----------------- | |
31 | |
32 The DICOM standard can be very roughly divided in 2 parts: | |
33 | |
34 1. The part specifying the DICOM **file format**. | |
35 2. The part specifying the DICOM **network protocol**. | |
36 | |
37 The DICOM file format is the topic of the present section. It is | |
38 inherently similar to well-known formats such as JPEG, PNG or | |
39 TIFF. However, besides the so-called "**pixel data**" that encodes the | |
40 medical image itself, a DICOM file also embeds medical information. | |
41 | |
42 | |
43 .. _dicom-tags: | |
44 | |
45 DICOM tags | |
46 ^^^^^^^^^^ | |
47 | |
48 The medical information encoded by a DICOM file is called a **data | |
49 set** and takes the form of a `key-value associative array | |
50 <https://en.wikipedia.org/wiki/Associative_array>`__. Each value can | |
51 itself be a list of data sets (called a **sequence**), leading to a | |
52 hierarchical data structure that is much like a XML or JSON file. | |
53 | |
54 In the DICOM terminology, each key is called a **DICOM tag**. The list | |
55 of the standard DICOM tags are normalized by an official dictionary, | |
56 each tag being identified by two 16-bit hexadecimal numbers. For | |
57 instance, the birth date of a patient is associated with the DICOM tag | |
58 ``(0x0010, 0x0030)``. Note that it is common to drop the "``0x``" | |
59 prefix and to simply write ``0010,0030``. For better readability, it | |
60 is also common to nickname these DICOM tags with a `camel case | |
61 <https://en.wikipedia.org/wiki/CamelCase>`__ English name (such as | |
62 "*PatientName*" or "*StudyDescription*"). The standard associates each | |
63 DICOM tag with a data type (a string, a date, a floating-point | |
64 number...), that is known as its **value representation**. | |
65 | |
66 Here is how :ref:`Orthanc Explorer <orthanc-explorer>` displays the | |
67 DICOM tags stored in a DICOM file (note that the file contains a | |
68 sequence identified by the tag ``ProcedureCodeSequence (0x0008, | |
69 0x1032)``): | |
70 | |
71 .. image:: images/DicomTags.png | |
72 :align: center | |
73 :width: 450px | |
74 | |
75 | | |
76 | |
77 The DICOM file format also specifies the set of DICOM tags that are | |
78 mandatory or optional for each kind of imaging modality (CT, MR, NM, | |
79 CBCT, PET...). Such a specification is called a **storage | |
80 service-object pair** (storage SOP). Mandatory tags are called "*type | |
81 1*", mandatory tags that can have a null value are called "*type 2*", | |
82 and optional tags are called "*type 3*". | |
83 | |
84 The DICOM standard also allows vendors to introduce non-standard, | |
85 **proprietary tags** for their own use. Proprietary tags can be | |
86 identified by the fact that their first hexadecimal number is odd | |
87 (e.g. ``(0x0009, 0x0010)``). Obviously, such proprietary tags should | |
88 be avoided for maximal interoperability. | |
89 | |
90 | |
91 .. _dicom-pixel-data: | |
92 | |
93 Pixel data | |
94 ^^^^^^^^^^ | |
95 | |
96 The image itself is associated with the DICOM tag ``PixelData (0x7fe0, | |
97 0x0010)``. The content of image can be compressed using many image | |
98 formats, such as JPEG, `Lossless JPEG | |
99 <https://en.wikipedia.org/wiki/Lossless_JPEG>`__ or `JPEG 2000 | |
100 <https://en.wikipedia.org/wiki/JPEG_2000>`__. Obviously, | |
101 non-destructive (lossless) compression should always be favored to | |
102 avoid any loss of medical information. Note that a DICOM file can also | |
103 act as a wrapper around a video encoded using `MPEG-2 | |
104 <https://en.wikipedia.org/wiki/MPEG-2>`__ or `H.264 | |
105 <https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC>`__. | |
106 | |
107 The image compression algorithm can be identified by inspecting the | |
108 **transfer syntax** that is associated with the DICOM file in its | |
109 header. | |
110 | |
111 In practice, few imaging devices in hospitals (besides the `PACS | |
112 <https://en.wikipedia.org/wiki/Picture_archiving_and_communication_system>`__ | |
113 itself) support image compression. As a consequence, to ensure best | |
114 portability, the pixel data of most DICOM files circulating in | |
427
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
115 hospitals is generally **uncompressed**. In other words, the image is |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
116 encoded as a raw buffer, with a given width, height, pixel type |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
117 (integer or float), `color depth |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
118 <https://en.wikipedia.org/wiki/Color_depth>`__ (most often 8, 10, 12 |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
119 bpp - *bits per pixel*) and photometric interpretation (most often |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
120 grayscale or RGB). The transfer syntax that is associated with such |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
121 uncompressed images can either be `little endian |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
122 <https://fr.wikipedia.org/wiki/Endianness>`__ (the most common case) |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
123 or big endian (retired in recent versions of the DICOM standard). |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
124 |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
125 The process of converting one DICOM instance from some transfer syntax |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
126 to another one is referred to as **transcoding**. The topic of |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
127 transcoding is covered in a :ref:`separate FAQ entry <transcoding>`. |
0 | 128 |
129 A DICOM image can be **multi-frame**, meaning that it encodes an array | |
130 of different image frames. This is for instance used to encode | |
131 uncompressed video sequences, that are often referred to as **cine** | |
132 or **2D+t** images (e.g. for `ultrasound imaging | |
133 <https://en.wikipedia.org/wiki/Medical_ultrasound>`__). | |
134 | |
135 `As written in its DICOM conformance statement | |
449 | 136 <https://hg.orthanc-server.com/orthanc/file/default/OrthancServer/Resources/DicomConformanceStatement.txt>`__, |
0 | 137 the Orthanc software can receive, store and send any kind of DICOM |
138 images (i.e. all the standard transfer syntaxes are | |
139 supported). Furthermore, Orthanc can :ref:`convert most uncompressed | |
140 images <supported-images>` to PNG images. The `PNG format | |
141 <https://en.wikipedia.org/wiki/Portable_Network_Graphics>`__ was | |
142 chosen by Orthanc as it is lossless, is natively supported by many | |
143 browsers, software or programming frameworks, and is able to encode up | |
144 to 16bpp integer pixels. This on-the-fly conversion to PNG images is | |
145 what happens when previewing a DICOM image within :ref:`Orthanc | |
146 Explorer <orthanc-explorer>`: | |
147 | |
148 .. image:: images/PreviewInstance.png | |
149 :align: center | |
150 :width: 400px | |
151 | |
152 | |
28 | 153 .. _model-world: |
154 | |
0 | 155 Model of the real world |
156 ^^^^^^^^^^^^^^^^^^^^^^^ | |
157 | |
158 This concludes our overview of the DICOM file format itself. It is now | |
159 important to give an overview of the so-called "**DICOM model of the | |
160 real world**" (`source | |
25 | 161 <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#sect_C.6.1.1>`__): |
0 | 162 |
163 .. image:: images/PS3.4_C.6-1.svg | |
164 :align: center | |
165 :height: 400px | |
166 | |
167 This UML diagram shows that a given **patient** benefits during her | |
168 life from a set of medical imaging **studies**. Each study is made of | |
169 a set of **series**. Each series is in turn a set of **instances**, | |
170 the latter being a synonym for a single DICOM file. In Orthanc's | |
171 vocabulary, a **DICOM resource** is an umbrella term to talk either | |
172 about a patient, a study, a series or an instance. | |
173 | |
174 Any imaging study can be associated with multiple series of | |
175 images. This is especially visible with nuclear medicine, as any | |
176 `PET-CT-scan <https://en.wikipedia.org/wiki/PET-CT>`__ study will | |
177 contain at least two separate series: the CT series and the PET | |
178 series. But any kind of imaging study will usually generate a set of | |
179 separate series. In general, a series can be thought of as either a | |
180 single 2D image (as in standard `digital radiography | |
181 <https://en.wikipedia.org/wiki/Digital_radiography>`__), a single 3D | |
182 volume (as in a `CT-scan <https://en.wikipedia.org/wiki/CT_scan>`__), | |
183 or a 2D+t cine sequence. But a series might also encode a single PDF | |
184 report, a `structured report | |
185 <http://www.dclunie.com/pixelmed/DICOMSR.book.pdf>`__, a 3D+t image | |
186 (i.e. a temporal sequence of 3D images)... | |
187 | |
188 In any case, the actual pixel data of a given series is spread across | |
189 multiple DICOM instances. This allows to split a single huge image | |
190 (medical imaging commonly deals with 4GB images) into hundreds of | |
191 small files of several megabytes, each of which can entirely fit in | |
192 the computer memory, at the price of a severe redundancy of the | |
193 medical information that is embedded within these files. | |
194 | |
195 For each of these 4 kinds of DICOM resources, the DICOM standard | |
196 specifies a **module** as a set of DICOM tags that describe these | |
197 resources. For instance, the DICOM tag *PatientName* is part of the | |
198 patient module, whereas *SeriesDescription* is part of the series | |
199 module. Any storage service-object pair (as :ref:`defined above | |
200 <dicom-tags>`) can be decomposed into a set of modules that make sense | |
201 for its associated type of modality, and whose conjunction forms | |
202 encodes all the medical information. | |
203 | |
204 According to this model of the real world, the default Web interface | |
205 of Orthanc allows to browse from the patient level to the instance | |
206 level. Here is how :ref:`Orthanc Explorer <orthanc-explorer>` displays | |
207 a series: | |
208 | |
209 .. image:: images/RealWorld.png | |
210 :align: center | |
211 :width: 450px | |
212 | |
213 | | |
214 | |
215 On the left side of the interface, an overview of the patient module, | |
216 the study module and the series module is displayed. On the right side, | |
217 the multiple instances of the series are accessible. | |
218 | |
219 | |
220 .. _dicom-identifiers: | |
221 | |
222 DICOM identifiers | |
223 ^^^^^^^^^^^^^^^^^ | |
224 | |
225 Very importantly, the DICOM standard specifies DICOM tags that allow | |
226 to index each single DICOM resource: | |
227 | |
228 * Patients are indexed with ``PatientID (0x0010, 0x0020)`` (part of the patient module). | |
229 * Studies are indexed with ``StudyInstanceUID (0x0020, 0x000d)`` (part of the study module). | |
230 * Series are indexed with ``SeriesInstanceUID (0x0020, 0x000e)`` (part of the series module). | |
231 * Instances are indexed with ``SOPInstanceUID (0x0008, 0x0018)`` (part of the SOP module). | |
232 | |
233 The DICOM standard orders *StudyInstanceUID*, *SeriesInstanceUID* and | |
234 *SOPInstanceUID* to be `globally unique | |
235 <https://en.wikipedia.org/wiki/Globally_unique_identifier>`__. In | |
236 other words, it is mandatory for two different imaging devices to | |
237 never generate the same identifiers, even if they are manufactured by | |
238 different vendors. Orthanc exploits this rule to derive its :ref:`own | |
239 unique identifiers <orthanc-ids>`. | |
240 | |
241 Importantly, even if the *PatientID* must be unique inside a given | |
242 hospital, it is not guaranteed to be globally unique. This means that | |
243 different patients imaged in different hospitals might share the same | |
244 *PatientID*. For this reason, you should always browse from the study | |
245 level (and not from the patient level) as soon as you deal with an | |
246 application that handles patients from different hospitals. | |
247 | |
166 | 248 *Note:* Note that since Orthanc 1.4.0, the :ref:`Orthanc Explorer |
249 <orthanc-explorer>` interface provides a new tab entitled "Studies" | |
250 for study-level access. | |
0 | 251 |
252 Finally, the patient module is not always fully meaningful. This is | |
253 for instance the case in emergency imaging, where the `radiology | |
254 information system | |
255 <https://en.wikipedia.org/wiki/Radiology_information_system>`__ might | |
256 not have previously encountered the imaged patient. In such a case, an | |
257 unique ``AccessionNumber (0x0008, 0x0050)`` is associated with the | |
258 imaging study by the imaging device of the emergency room: The patient | |
259 module will be injected later on in the PACS once the administrative | |
260 information is available, as part of a reconciliation process. | |
261 | |
262 In any case, the core engine Orthanc keeps an index of all these DICOM | |
263 identifiers (*PatientID*, *AccessionNumber*, *StudyInstanceUID*, | |
264 *SeriesInstanceUID* and *SOPInstanceUID*) and is able to quickly maps | |
265 them to its own :ref:`internal identifiers <orthanc-ids>`. This lookup | |
266 is implemented by the ``/tools/lookup`` URI of the :ref:`REST API of | |
267 Orthanc <rest>`. | |
268 | |
269 | |
238 | 270 .. _dicom-protocol: |
271 | |
0 | 272 DICOM network protocol |
273 ---------------------- | |
274 | |
275 This concludes our overview of the DICOM file format. :ref:`As written | |
276 above <dicom-format>`, we now describe the second main part of the | |
277 DICOM standard, i.e. the **DICOM network protocol**. | |
278 | |
279 | |
280 .. _dicom-protocol-overview: | |
281 | |
282 Overview | |
283 ^^^^^^^^ | |
284 | |
285 The DICOM protocol is actually one of the earliest example of `Web | |
286 services <https://en.wikipedia.org/wiki/Web_service>`__, long before | |
287 the introduction of `SOAP <https://en.wikipedia.org/wiki/SOAP>`__ or | |
288 `REST | |
289 <https://en.wikipedia.org/wiki/Representational_state_transfer>`__. It | |
290 allows to: | |
291 | |
292 1. **Test the connection** between two devices (:ref:`C-Echo | |
293 <dicom-echo>`). | |
294 2. **Send images** from the local imaging device to a remote device | |
295 (:ref:`C-Store <dicom-store>`). | |
296 3. **Search the content** of a remote device (:ref:`C-Find <dicom-find>`). | |
421
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
297 4. **Retrieve images** from a remote device (:ref:`C-Move |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
298 <dicom-move>` or :ref:`C-Get <dicom-get>`). |
0 | 299 |
300 Here is a picture that summarizes some key concepts: | |
301 | |
302 .. image:: images/Protocol.svg | |
303 :height: 200px | |
304 :align: center | |
305 | |
306 In the DICOM terminology, the client of a DICOM service is called a | |
307 **service class user** (SCU), and the server that handles the requests | |
308 is called a **service class provider** (SCP). The client sends a | |
309 request that is encoded as a DICOM file (the **command**), and the | |
310 server answers with a DICOM file. | |
311 | |
312 The connection of a DICOM client to a DICOM server is called an | |
313 **association**. Such an association starts with a handshake where the | |
314 client and the server agree on which commands can be exchanged between | |
315 them, and on which :ref:`transfer syntaxes <dicom-pixel-data>` are | |
316 supported. The result of this negotiation is called the **presentation | |
317 context**. Once the association is negotiated, this communication | |
318 channel can be used to successively send multiple, independent | |
319 commands. | |
320 | |
321 | |
322 Parameters of a DICOM server | |
323 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
324 | |
325 Historically, the DICOM protocol was designed to work over | |
326 `point-to-point links | |
327 <https://en.wikipedia.org/wiki/Point-to-point_(telecommunications)>`__. | |
328 Nowadays, the DICOM protocol is used over the `TCP/IP stack | |
329 <https://en.wikipedia.org/wiki/Internet_protocol_suite>`__. This | |
330 implies that a DICOM server can be identified by specifying the | |
331 parameters of its `network socket | |
332 <https://en.wikipedia.org/wiki/Network_socket>`__: | |
333 | |
334 1. Its **IP address** (or, equivalently, its symbolic DNS hostname). | |
335 2. Its **TCP port** (the standard DICOM port is 104, but Orthanc uses | |
336 the non-priviliged port 4242 by default). | |
337 | |
338 Furthermore, each imaging device (may it be a client or a server) must | |
339 be associated with a symbolic name that is called the **application | |
340 entity title (AET)**. The AET is assumed to be unique inside the | |
341 Intranet of the hospital. For best compatibility between vendors, the | |
342 AET should be only made of alphanumeric characters in upper case (plus | |
343 the "``-``" and "``_``" characters), and its length must be below 16 | |
344 characters. | |
345 | |
346 Taken together, the IP address, the TCP port and the AET describe all | |
347 the parameters of a DICOM server. The administrators of a medical | |
348 imaging network should carefully keep track of these parameters for | |
349 each imaging device, and should define an hospital-wide policy to | |
350 assign AETs to new devices. | |
351 | |
352 | |
353 Configuring Orthanc | |
354 ^^^^^^^^^^^^^^^^^^^ | |
355 | |
356 Orthanc can act both as a DICOM client and as a DICOM server, | |
357 depending on the parameters in its :ref:`configuration file | |
358 <configuration>`. To configure the **DICOM server** of Orthanc, the | |
359 following options are especially important: | |
360 | |
361 1. ``DicomServerEnabled`` must be set to ``true``. | |
362 2. ``DicomAet`` must be set to the AET that is reserved to Orthanc. | |
363 3. ``DicomPort`` specifies the TCP port of the DICOM server. | |
364 | |
365 To configure Orthanc as a **DICOM client**, you must list the remote DICOM | |
366 servers that are known to Orthanc into the ``DicomModalities`` option. | |
367 For each remote server, you must specify in the following order: | |
368 | |
369 1. An user-friendly, symbolic name for the server that will be | |
370 displayed by :ref:`Orthanc Explorer <orthanc-explorer>` (possibly | |
371 its AET). | |
372 2. The AET of the remote server. | |
373 3. Its IP address or its hostname. | |
374 4. Its DICOM port (most probably 104, or 4242 if the remote server is | |
375 another instance of Orthanc). | |
376 | |
377 Of course, after any change to the configuration of Orthanc, the | |
378 software must be restarted to take the new parameters into account. | |
379 | |
380 | |
381 .. _dicom-echo: | |
382 | |
383 C-Echo: Testing connectivity | |
384 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
385 | |
386 Routers might block the DICOM protocol between separate `subnets | |
387 <https://en.wikipedia.org/wiki/Subnetwork>`__ (often, only the HTTP, | |
388 HTTPS and SSH protocols are enabled by default). Furthermore, the | |
389 firewalls that are installed on the clients or on the servers might | |
390 also block the DICOM protocol. This is especially true for the | |
391 `Microsoft Windows firewall | |
392 <https://en.wikipedia.org/wiki/Windows_Firewall>`__ and for | |
42 | 393 :ref:`RedHat-based GNU/Linux boxes <redhat>`. As a consequence, after |
394 any change in the DICOM topology of an hospital (notably when | |
395 connecting two imaging devices), one should always check whether the | |
396 DICOM protocol can travel from end to end, i.e. between the DICOM | |
397 client and the DICOM server. | |
0 | 398 |
399 This is where the **DICOM Echo service** comes into play. This service | |
400 is triggered when the client sends a so-called ``C-Echo`` command to | |
401 the server as its DICOM query. The server answers with an empty DICOM | |
402 answer. In practice, to test the connectivity between two devices, you | |
403 should: | |
404 | |
405 1. Use the standard command-line tool ``ping`` to test the **TCP-level | |
406 connectivity** between the client and the server, then | |
407 2. Issue the **C-Echo** from the client to the server to test the | |
408 DICOM-level connectivity. | |
409 | |
410 The second step can be done directly from :ref:`Orthanc Explorer | |
411 <orthanc-explorer>`, the embedded administrative interface of Orthanc, | |
412 in the "*Query/Retrieve*" panel, as depicted below: | |
413 | |
414 .. image:: images/Echo.png | |
415 :align: center | |
416 :width: 450px | |
417 | |
418 | | |
419 | |
420 In this screenshot, ``sample`` corresponds to the symbolic name of a | |
421 DICOM server that is declared in the ``DicomModalities`` | |
422 :ref:`configuration option <configuration>`. Once DICOM Echo succeeds, | |
423 the client should be able to send images to the server, and to | |
424 initiate a query/retrieve. This is the topic of the following | |
425 sections. | |
426 | |
427 | |
428 .. _dicom-store: | |
429 | |
430 C-Store: Sending images to a server | |
431 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
432 | |
433 The **DICOM Store Service** is used to send DICOM instances to a | |
434 remote imaging device. This service is triggered when the client sends | |
435 to the server a so-called ``C-Store`` command together with the | |
436 content of a DICOM instance. Schematically, C-Store works as follows: | |
437 | |
438 .. image:: images/CStore.svg | |
439 :align: center | |
440 :width: 500px | |
441 | |
442 Orthanc can act both as a C-Store client (SCU) or as a C-Store server | |
443 (SCP). In other words, it can either send or receive DICOM files. | |
444 | |
445 In the :ref:`Orthanc Explorer <orthanc-explorer>` interface, each | |
446 DICOM resource (patient, study, series or instance) comes with a | |
447 button entitled "*Send to remote modality*". Clicking on this button | |
448 allows to send the image to any DICOM server that is declared in the | |
449 ``DicomModalities`` :ref:`configuration option <configuration>`. In | |
450 the following screenshot, all the instances of one patient will be | |
451 sent to the device whose symbolic name is ``sample``: | |
452 | |
453 .. image:: images/CStoreGui.png | |
454 :align: center | |
455 :width: 450px | |
456 | |
457 | |
458 .. _dicom-find: | |
459 | |
460 C-Find: Browsing the content of a server | |
461 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
462 | |
463 The **DICOM Find Service** is used to **search** a list of DICOM | |
464 resources that are hosted by some remote DICOM server. The kind of | |
465 resource that is looked for (patients, studies or series) must be | |
466 specified, leading to the **query level** of the query. Besides the | |
467 query level, the query contains a set of filters on DICOM tags of | |
468 interest: These filters are essentially `wildcards | |
469 <https://en.wikipedia.org/wiki/Glob_(programming)>`__ describing the | |
470 resources that are looked for. This service is triggered when the | |
471 client sends to the server a so-called ``C-Find`` command that encodes | |
472 the query level and the filters. Schematically, C-Find works as | |
473 follows: | |
474 | |
475 .. image:: images/CFind.svg | |
476 :align: center | |
477 :width: 500px | |
478 | |
479 Orthanc can act both as a C-Find client (SCU) or as a C-Find server | |
480 (SCP). In other words, it can be used to search the content of a | |
481 remote server, and conversely it can inform a remote client about its | |
482 own content. | |
483 | |
484 In the :ref:`Orthanc Explorer <orthanc-explorer>` interface, it | |
485 is possible to initiate a search at the study level. This feature | |
486 is available in the "*Query/Retrieve*" panel, as depicted below: | |
487 | |
488 .. image:: images/CFindGui1.png | |
489 :align: center | |
490 :width: 500px | |
491 | |
492 | | |
493 | |
494 This screenshot shows that we are looking for a study whose associated | |
495 patient has a name that starts with "*Brain*", and that is of MR | |
496 modality. Orthanc Explorer then lists the matching studies: | |
497 | |
498 .. image:: images/CFindGui2.png | |
499 :align: center | |
500 :width: 500px | |
501 | |
502 | | |
503 | |
504 It is then possible to click on some matching study, to list the | |
505 individual series it is made of: | |
506 | |
507 .. image:: images/CFindGui3.png | |
508 :align: center | |
509 :width: 500px | |
510 | |
511 | |
512 .. _dicom-move: | |
513 | |
514 C-Move: Query/retrieve | |
515 ^^^^^^^^^^^^^^^^^^^^^^ | |
516 | |
517 This brings us to the last important component of the DICOM network | |
518 protocol, the **DICOM Move Service**. This service is notably used to | |
519 locally retrieve DICOM files from a remote server, given the results | |
520 of a :ref:`C-Find query <dicom-find>`. Taken together, ``C-Find`` and | |
521 ``C-Move`` give rise to the **query/retrieve** mechanism at is at the | |
522 core of the exchange of DICOM files within the hospital. | |
523 | |
524 C-Move is probably the part of the DICOM standard that is the less | |
525 intuitive, which leads to many configuration problems in medical | |
526 imaging networks. This stems from the fact that C-Move is actually not | |
527 limited to query/retrieve. It is a more generic protocol that can | |
528 involve up to **3 distinct imaging devices**, as depicted below: | |
529 | |
530 .. image:: images/CMove.svg | |
531 :align: center | |
532 :width: 500px | |
533 | |
534 Whenever an imaging device (called the *issuer* above) initiates a | |
535 C-Move command, it asks a DICOM server (called the *source* above) to | |
536 send some of its images to another DICOM server (called the *target* | |
537 above). Accordingly, a C-Move command encodes the :ref:`identifiers | |
538 <dicom-identifiers>` of the DICOM resources to be sent, together with | |
539 the AET of the target server. To put it in other words, a C-Move | |
540 command drives a **C-Store between two remote DICOM servers** (the | |
541 *source* and the *target*). | |
542 | |
543 The query/retrieve mechanism corresponds to the special case of a | |
544 C-Move command where the target and the issuer are the same imaging | |
545 device. The most common configuration problem for query/retrieve is | |
546 therefore to forget to declare the AET of the "*issuer/target*" device | |
547 into the configuration of the "*source*" device. | |
548 | |
549 Orthanc can act both as a C-Move client (SCU) or as a C-Move server | |
550 (SCP). This implies that Orthanc can either initiate a query/retrieve, | |
551 or be driven as part of a query/retrieve request. You might want to | |
552 give a look at the ":ref:`query-retrieve`" section of this book to | |
553 learn how to concretely configure Orthanc for query/retrieve. | |
554 | |
555 A C-Move session can be initiated from the :ref:`Orthanc Explorer | |
556 <orthanc-explorer>` interface, after a :ref:`C-Find query | |
557 <dicom-find>` is complete. It is sufficient to click on the download | |
558 button that is to the right of the study or series of interest: | |
559 | |
560 .. image:: images/CMoveGui1.png | |
561 :align: center | |
562 :width: 500px | |
563 | |
564 | | |
565 | |
566 A dialog box then pops up, asking the AET of the *target* modality. | |
567 By default, this field is pre-filled with the AET of Orthanc, which | |
568 corresponds to the initiation of a query/retrieve: | |
569 | |
570 .. image:: images/CMoveGui2.png | |
571 :align: center | |
572 :width: 500px | |
573 | |
574 | | |
575 | |
9
6e99967d3503
C-GET is not deprecated
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
576 *Note 1:* Even if C-Move may seem counter-intuitive, this is the most |
6e99967d3503
C-GET is not deprecated
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
577 popular and widespread way to initiate a query/retrieve against a PACS |
421
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
578 server. The DICOM standard features an alternative mechanism called |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
579 :ref:`DICOM C-Get <dicom-get>` that has been introduced in Orthanc |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
580 1.7.0 (see below). |
0 | 581 |
582 *Note 2:* As :ref:`written above <dicom-pixel-data>`, the Orthanc | |
427
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
583 engine is quite generic and is compatible with many image compression |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
584 algorithms (aka. transfer syntax). In particular, during the |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
585 :ref:`negotiation of a presentation context |
0 | 586 <dicom-protocol-overview>`, Orthanc reports by default that it is |
587 compatible with the JPEG 2000 encoding. This leads some PACS engines | |
588 to compress their images before sending them to Orthanc, so as to | |
589 reduce the network bandwidth. Unfortunately, because many medical | |
590 image analysis software are not compatible with such an image | |
427
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
591 compression, the JPEG 2000 image that is received by Orthanc might not |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
592 be usable by such software. Check out the :ref:`FAQ about DICOM |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
593 transcoding <transcoding>` for more information about converting |
71281b540ca1
updating old documentation about transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
421
diff
changeset
|
594 between transfer syntaxes over the DICOM protocol. |
0 | 595 |
596 | |
412 | 597 .. _dicom-get: |
598 | |
421
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
599 C-Get: Retrieve with one single SCP |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
600 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
601 |
430
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
602 Orthanc 1.7.0 introduces support for DICOM C-Get SCP. DICOM C-Get |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
603 provides a simpler alternative to DICOM C-Move, if the *issuer* and |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
604 the *target* (as depicted in the section about :ref:`C-Move |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
605 <dicom-move>`) correspond to the same modality: |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
606 |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
607 .. image:: images/CGet.svg |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
608 :align: center |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
609 :width: 500px |
421
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
610 |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
611 In the case of C-Get, contrarily to C-Move, the *target* modality |
430
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
612 doesn't need to act as a C-Store SCP: The requested data is sent |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
613 directly back to the client over the same DICOM association the C-Get |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
614 request is made on. Therefore C-Get request does not depend on |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
615 separate associations being established to move DICOM from a remove |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
616 source to a remove target. Instead C-Get "turns around" the same |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
617 connection on which the request is made, and re-uses the connection to |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
618 receive the inbound C-Store operation. |
412 | 619 |
430
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
620 This has advantage of simplifying the design of the SCU (only one |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
621 DICOM server is needed in the *source* modality), and to ease the |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
622 network configuration (instead of being bidirectional as in |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
623 query/retrieve through C-Move, C-Get is unidirectional from *issuer* |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
624 to *source*, which simplifies firewall rules). Nevertheless, C-Get is |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
625 less generic than C-Move and less often encountered in clinical PACS |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
626 workflow. It is more often used by DICOM viewers. Also note that |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
627 :ref:`DICOMweb WADO-RS <dicomweb>` is designed for the same kind of |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
628 use cases than C-Get. |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
629 |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
630 For a complete description of the C-Get DICOM Request and a review of |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
631 the advantages of C-Get over C-Move, have a look at `David Clunie's |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
632 dedicated blog post |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
633 <http://dclunie.blogspot.be/2016/05/to-c-move-is-human-to-c-get-divine.html>`__. |
421
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
634 |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
635 .. highlight:: json |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
636 |
430
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
637 In practice, to retrieve DICOM instances using C-Get, you must provide |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
638 one ore more of the unique key attributes (``PatientID``, |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
639 ``StudyInstanceUID``, ``SeriesInstanceUID`` or |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
640 ``SOPInstanceUID``). This information can for instance be retrieved |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
641 through a :ref:`C-Find request <dicom-find>`. As an example, let us |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
642 consider the following minimalist :ref:`Orthanc configuration |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
643 <configuration>`:: |
412 | 644 |
421
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
645 { |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
646 "DicomModalities" : { |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
647 "getscu" : [ "GETSCU", "localhost", 2000 ] |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
648 } |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
649 } |
412 | 650 |
421
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
651 .. highlight:: text |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
652 |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
653 Given this configuration, here is a sample command-line to call the |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
654 C-Get SCP of Orthanc using the `DCMTK |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
655 <https://support.dcmtk.org/docs/dcmconv.html>`__ toolkit, given some |
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
656 known ``StudyInstanceUID``:: |
412 | 657 |
421
e0b4b88446a8
expanded notes about c-get
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
413
diff
changeset
|
658 $ getscu -v localhost 4242 -aec ORTHANC -k "0008,0052=STUDY" -k "0020,000d=1.2.840.113543.6.6.4.7.64067529866380271256212683512383713111129" |
412 | 659 |
528 | 660 *Note:* As of Orthanc 1.8.0, Orthanc implements C-Get as a service |
430
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
661 class provider (SCP). Using C-Get as a service class user (SCU) is not |
c3e73c00ef48
adding explanations about C-Get from Varian
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
427
diff
changeset
|
662 currently supported in Orthanc. |
412 | 663 |
664 | |
0 | 665 |
666 Using HTTP instead of the DICOM protocol | |
667 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
668 | |
669 We conclude this brief overview of DICOM by insisting on the fact that | |
670 the **DICOM protocol inherently targets the Intranet** of a single | |
671 hospital, not the Internet or the cloud. This protocol might be | |
672 blocked by outbound firewalls, and there is no convention ensuring | |
673 that the AETs are globally unique across all the | |
674 hospitals. Furthermore, even though the DICOM protocol supports TLS | |
675 encryption, this feature is rarely enabled. | |
676 | |
677 Depending on your application, you might therefore want to leverage | |
678 the **HTTP protocol** in the context of DICOM. Such Web-based | |
679 protocols are probably more familiar to physicians/physicists/software | |
680 engineers, are easier to work with, can be transparently encrypted | |
681 (**HTTPS**), and are compatible with multiple-hospital scenarios. To | |
682 this end, you have two possibilities: | |
683 | |
684 1. Resort to the :ref:`Orthanc peer <peers>` mechanism. Because each | |
685 Orthanc server comes with its built-in :ref:`REST API <rest>`, | |
686 remote systems can obtain a full programmatic control over the | |
687 content of Orthanc. This access can be secured by HTTP | |
688 authentication and :ref:`SSL encryption <https>`. The :ref:`Orthanc | |
689 Explorer <orthanc-explorer>` interface can transparently use this | |
690 peer mechanism to send DICOM files over HTTP(S). | |
358
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
691 2. Resort to the `DICOMweb standard |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
692 <https://www.dicomstandard.org/dicomweb/>`__, that is an extension |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
693 to the DICOM standard specifying how to access the content of a |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
694 remote DICOM server through HTTP(S). Because the peer mechanism is |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
695 bound to Orthanc, DICOMweb offers a less expressive, but more |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
696 generic access to remote servers. Importantly, a `DICOMweb plugin |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
697 to Orthanc |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
238
diff
changeset
|
698 <https://www.orthanc-server.com/static.php?page=dicomweb>`__ is |
0 | 699 freely available. |