Découverte de DICOM, le format d'imagerie médicale - PARTIE 2 : les données

Après un premier article plutôt théorique dans lequel on avait parlé de la structure des fichiers DICOM (format utilisé pour l'imagerie médicale), on se retrouve aujourd'hui dans un second article plus orienté « mains dans le cambouis ». On va cette fois-ci voir concrètement comment confectionner à la main un fichier DICOM avec des données médicales à l'intérieur et tout. 😲️

On va commencer par détailler tous les éléments obligatoires qui composent l'entête (partie « Meta Information ») d'un fichier DICOM, et on verra ensuite de quelle manière aborder le remplissage du Data Set (corps du fichier) avec des données sur le patient et une image issue d'un scanner.

Pour l'entête, je vais aborder les champs dans l'ordre dans lequel ils doivent apparaitre dans le fichier. Pour le corps en revanche je vais les grouper par module logique : ça sera plus simple de procéder ainsi car c'est la manière dont est structuré la spec DICOM. Gardez donc bien à l'esprit qu'il faudra les trier par tag croissant au moment de les écrire dans le fichier !

Notez également que le fichier qu'on va créer ne sera en réalité pas tout à fait complet, sinon l'article serait trop long, mais je vous donnerai toutes les informations utiles pour le compléter par vous-mêmes. 😉️

Je n'ai pas encore réussi à vous faire fuir ? Alors on se lance ! 😄️

Note

Cet article fait partie d'une série de deux articles sur DICOM, le format d'imagerie médicale :

  1. Découverte de DICOM, le format d'imagerie médicale - PARTIE 1 : la structure
  2. Découverte de DICOM, le format d'imagerie médicale - PARTIE 2 : les données

L'entête (partie « Meta Information »)

Du coup, forcément, on va commencer par l'entête. Vous trouverez la liste de tous les éléments qui le compose dans le tableau PS3.10 7.1-1 de la norme :

Ce tableau donne toutes les informations sur les données à placer dans chaque élément... mais il ne donne pas le type des données (VR). Vous trouverez cette information dans une autre partie de la spec, et plus précisément dans le tableau 7-1 de la 6ème partie :

Et si jamais vous vous demandez à quoi correspond la colonne « Type » du tableau PS3.10 7.1-1, bah sachez que le type 1 signifie que l'attribut est obligatoire, le type 1C signifie que l'élément est obligatoire MAIS dans certaines conditions seulement, et le type 3 indique quant à lui que l'attribut est optionnel... Vous retrouverez cette information avec davantage de détails dans la section PS3.10 5 :

File Preamble et DICOM Prefix

Comme on l'a vu dans le précédent article, un fichier DICOM commence par un préambule et un préfixe qui ne sont pas encapsulés dans une structure de donnée, ce qui nous donne quelque chose comme ça :

  Donnée
File Preamble
Interprétation vide (préambule inutilisé)
Donnée binaire
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
DICOM Prefix
Interprétation DICM
Donnée binaire 44 49 43 4D

File Meta Information Group Length (0002,0000)

Ensuite vient notre premier élément de donnée structuré. Ce champ donne la longueur restante de la partie Meta Information, donc le nombre d'octets de l'entête sans compter le préambule, le préfixe et cette première structure. Pour le moment je laisse cette valeur vide, on la remplira à la fin puis qu'il faudra compter nos octets... 😅️

(7.1-2) Tag VR VL Value
Interprétation (0002,0000) UL 4 ❓️
Donnée binaire 02 00 00 00 55 4C 04 00 XX XX XX XX

File Meta Information Version (0002,0001)

On poursuit avec la version de l'entête, qui s'écrit sous forme de flags : la valeur ne s'interprète pas comme un nombre mais les bits passent à 1 pour indiquer le support d'une version particulière, et ces versions sont cumulatives... Bref, on ne va pas rentrer dans les détails, ici il faudra juste toujours mettre la valeur 0x00 0x01. Attention le champ est de type « tableau d'octet », il n'est donc pas question de big ou de little endian ici, il faut écrire la valeur telle quelle ! 😉️

(7.1-1) Tag VR pad. VL Value
Interprétation (0002,0001) OB   2 version 1
Donnée binaire 02 00 01 00 4F 42 00 00 02 00 00 00 00 01

Media Storage SOP Class UID (0002,0002)

Maintenant on passe au « Media Storage SOP Class UID »... Derrière cette dénomination barbare se cache le type de donnée médicale que l'on va stocker dans le fichier DICOM : mammographie, courbe d'électrocardiogramme, tomodensitométrie (a.k.a scanographie ou scanner), image aux rayons X, etc.

Chaque type d'examen / de donnée se voit attribuer un identifiant unique que vous retrouverez dans le tableau ci-dessous :

Dans notre cas on va déclarer que notre fichier contient une image de type « CT Image » (« Computed Tomography » ou tomodensitométrie en français). Ce type d'image a pour identifiant unique "1.2.840.10008.5.1.4.1.1.2".

(7.1-2) Tag VR VL Value (pad?)
Interprétation (0002,0002) UI 26 1.2.840.10008.5.1.4.1.1.2
Donnée binaire 02 00 02 00 55 49 1A 00 31 2E 32 2E 38 34 30 2E 31 30 30 30 38 2E 35 2E 31 2E 34 2E 31 2E 31 2E 32 00

Media Storage SOP Instance UID (0002,0003)

Il s'agit d'un UID que vous pouvez à priori définir à la valeur que vous voulez mais qui doit être unique. Si vous avez une série de fichiers DICOM (ce qui est le cas pour les scanners et les IRM), vous pouvez par exemple donner comme ID 1.2.3.1 pour la première image, puis 1.2.3.2 pour la seconde, etc.

(7.1-2) Tag VR VL Value (pad?)
Interprétation (0002,0003) UI 6 1.2.3
Donnée binaire 02 00 03 00 55 49 06 00 31 2E 32 2E 33 00

Transfer Syntax UID (0002,0010)

On en a déjà pas mal parlé dans la première partie de l'article donc pas de surprise ici. Il faut déclarer dans cet attribut l'identifiant de la syntaxe de transfert que l'on va utiliser dans le Data Set. Pour rappel nous on va utiliser la « DICOM Explicit VR Little Endian Transfer Syntax » (PS3.5 A.2), qui a pour identifiant "1.2.840.10008.1.2.1".

(7.1-2) Tag VR VL Value (pad?)
Interprétation (0002,0010) UI 20 1.2.840.10008.1.2.1
Donnée binaire 02 00 10 00 55 49 14 00 31 2E 32 2E 38 34 30 2E 31 30 30 30 38 2E 31 2E 32 2E 31 00

Références utiles :

Implementation Class UID (0002,0012)

Bon pour celui-là j'ai pas 100 % compris, mais à priori c'est un identifiant unique qui sert à identifier le logiciel ou le matériel qui a servi à générer le fichier... À priori on peut mettre un peu ce qu'on veut, ça ne semble pas bien important à ce stade. 🤷‍♂️️

(7.1-2) Tag VR VL Value (pad?)
Interprétation (0002,0012) UI 8 1.2.3.4
Donnée binaire 02 00 12 00 55 49 08 00 31 2E 32 2E 33 2E 34 00

Implementation Version Name (0002,0013) [Optionnel]

Pour terminer, on va écrire le nom et la version de notre logiciel dans ce dernier champ [oui il est optionnel, mais ça me semble important de le définir au cas où un jour on chercherait à savoir qui a commis ce fichier DICOM qui ne respecte pas les standards ! 😛️].

(7.1-2) Tag VR VL Value (pad?)
Interprétation (0002,0013) SH 10 FLOZz 1.0
Donnée binaire 02 00 13 00 53 48 0A 00 46 4C 4F 5A 7A 20 31 2E 30 20

On finalise l'entête

Et voilà on a fait le tour des éléments à définir dans l'entête du fichier. On peut donc à présent compter nos octets pour remplir la toute première structure qu'on a vu. Notre entête fait 124 octets de long (en enlevant le préambule, le préfixe et la première structure). En hexa ça donne 0x7C, on va donc pouvoir écrire 0x7C 0x00 0x00 0x00 comme valeur dans la structure (entier 32 bits non signé encodé en little endian).

Une fois tout recollé ensemble ça nous donne ça :

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000080  44 49 43 4D 02 00 00 00  55 4C 04 00 7C 00 00 00  DICM....UL..|...
00000090  02 00 01 00 4F 42 00 00  02 00 00 00 00 01 02 00  ....OB..........
000000A0  02 00 55 49 1A 00 31 2E  32 2E 38 34 30 2E 31 30  ..UI..1.2.840.10
000000B0  30 30 38 2E 35 2E 31 2E  34 2E 31 2E 31 2E 32 00  008.5.1.4.1.1.2.
000000C0  02 00 03 00 55 49 06 00  31 2E 32 2E 33 00 02 00  ....UI..1.2.3...
000000D0  10 00 55 49 14 00 31 2E  32 2E 38 34 30 2E 31 30  ..UI..1.2.840.10
000000E0  30 30 38 2E 31 2E 32 2E  31 00 02 00 12 00 55 49  008.1.2.1.....UI
000000F0  08 00 31 2E 32 2E 33 2E  34 00 02 00 13 00 53 48  ..1.2.3.4.....SH
00000100  0A 00 46 4C 4F 5A 7A 20  31 2E 30 20              ..FLOZz 1.0

C'est un bon début, passons donc au Data Set ! 😄️

Le corps (partie « Data Set »)

Le Data Set d'un DICOM se compose de modules qui vont définir un certain nombre d'éléments de donnée obligatoires et optionnels qui proviennent de divers groupes. Ces modules ont chacun un objectif précis, comme fournir la fiche du patient, les informations sur un type d'examen particulier ou le stockage d'une image.

Certains éléments de données sont nécessaires à différents modules et la norme les définit donc dans chacun des modules concernés, mais il faudra cependant définir chaque élément qu'une seule fois dans le fichier final.

Schéma du découpage du Data Set en modules dont certains ont des éléments de données en commun

Schéma du découpage du Data Set en modules dont certains ont des éléments de données en commun

Comme pour l'entête, la spec des différents modules ne définit pas les types des données (VR), il faudra pour cela se référer au tableau PS3.6 6-1 de la norme DICOM :

Note

Rappel : Comme expliqué en introduction, pour cette partie on va regrouper les éléments de données par module pour que ça soit plus digeste. Il faudra cependant les retrier par tag croissant pour les écrire dans le fichier final.

SOP Common Module (PS3.3 C.12.1)

On commence notre tournée des modules par le « SOP Common Module » qui contient des informations nécessaires à l'identification du Data Set.

Ici on va définir 2 éléments de donnée :

  • SOP Class UID (0008,0016),
  • et SOP Instance UID (0008,0018).

Si ça vous dit quelque chose, c'est normal car ils correspondent respectivement aux éléments (0002,0002) et (0002,0003) que l'on a déjà définis dans l'entête du fichier et ils doivent contenir strictement la même valeur (enfin techniquement c'est ceux de l'entête qui doivent être identiques à ceux du Data Set mais bon vous avez compris 🙃️).

Voici concrètement à quoi tout ça ressemble :

(7.1-2) Tag VR VL Value (pad?)
SOP Class UID
Interprétation (0008,0016) UI 26 1.2.840.10008.5.1.4.1.1.2
Donnée binaire 08 00 16 00 55 49 1A 00 31 2E 32 2E 38 34 30 2E 31 30 30 30 38 2E 35 2E 31 2E 34 2E 31 2E 31 2E 32 00
SOP Instance UID
Interprétation (0008,0018) UI 6 1.2.3
Donnée binaire 08 00 18 00 55 49 06 00 31 2E 32 2E 33 00

Références utiles :

Patient Module (PS3.3 C.7.1.1)

Passons ensuite à la fiche du patient. Ici on va se contenter de définir son nom et un identifiant unique pour le représenter, ce qui correspond aux éléments de données suivants :

  • Patient's Name (0010,0010),
  • et Patient ID (0010,0020).
(7.1-2) Tag VR VL Value (pad?)
Patient's name
Interprétation (0010,0010) PN 14 Amanda^Ripley
Donnée binaire 10 00 10 00 50 4E 0E 00 41 6D 61 6E 64 61 5E 52 69 70 6C 65 79 20
Patient ID
Interprétation (0010,0020) LO 4 937
Donnée binaire 10 00 20 00 4C 4F 04 00 39 33 37 20

Références utiles :

CT Image Module (PS3.3 C.8.2.1)

Comme je l'ai mentionné quand on a parlé du « Media Storage SOP Class UID » dans l'entête, on va écrire une image censée être issue d'un scanner dans notre fichier DICOM. On va donc devoir définir les éléments de donnée issus du module « CT Image ».

Bon ici on ne va en définir qu'un :

  • Image Type (0008,0008)

Cet élément permet d'identifier les caractéristiques de l'image. Il s'agit d'une chaine de caractère qui contient (à priori) de 2 à 4 composantes que l'on va dans notre cas définir à "ORIGINAL\PRIMARY\AXIAL". Je ne vais pas rentrer dans les détails ici, mais si vous voulez en savoir plus, vous pouvez vous référer à la section PS3.3 C.7.6.1.1.2 de la norme pour les deux premières composantes, et à la section PS3.3 C.8.2.1.1.1 pour la troisième.

Ce module définit d'autres champs essentiels à l'interprétation de l'image, mais ils sont communs avec le module « Image Pixel Module » donc on en parlera juste après. 😉️

(7.1-2) Tag VR VL Value
Interprétation (0008,0008) CS 22 ORIGINAL\PRIMARY\AXIAL
Donnée binaire 08 00 08 00 43 53 16 00 4F 52 49 47 49 4E 41 4C 5C 50 52 49 4D 41 52 59 5C 41 58 49 41 4C

Références utiles :

Image Pixel Module (PS3.3 C.7.6.3)

Passons maintenant à l'image en elle-même. Vous trouverez la liste complète des éléments de données à définir dans le tableau PS3.3 C.7.11a, ainsi que dans le tableau PS3.3 C.7-11c (qui est référencé par le premier) :

On va commencer par définir les attributs qui permettent de caractériser l'image. Voici ceux dont on va avoir besoin :

  • Samples per Pixel (0028,0002) : Nombre de composantes pour chaque pixel de l'image. Dans notre cas il s'agira d'une image en niveau de gris, donc cette valeur sera à définir à 1. Si on avait voulu stocker une image couleur RGB, cette valeur aurait été à 3. Reportez-vous à la section PS3.3 C.7.6.3.1.1 de la spec pour plus d'informations.

  • Photometric Interpretation (0028,0004) : Interprétation graphique des octets qui composent l'image. Dans notre cas on mettra MONOCHROME2, ce qui signifie qu'un octet à 0 représente un pixel noir et un octet à la valeur maximale (255 pour cet exemple car on va coder les pixels sur 8 bits) représente un pixel blanc. Toutes les valeurs intermédiaires représentent un pixel gris plus ou moins lumineux. Il existe d'autres représentations comme MONOCHROME1 qui est simplement l'inverse du précédent (0 représente le blanc et la valeur maximale le noir), ou encore RGB pour une image en couleurs non indexées. Il en existe plein d'autres que vous retrouverez dans la section PS3.3 C.7.6.3.1.2.

  • Rows (0028,0010) : Hauteur de l'image. Dans notre cas elle fera 2 px de haut.

  • Columns (0028,0011) : Largeur de l'image. Dans notre cas elle fera 2 px de large.

  • Bits Allocated (0028,0100) : Nombre de bits à allouer pour chaque pixel de l'image. Dans notre cas ça sera 8. Les valeurs acceptables sont 1 (image monochrome, sans niveau de gris) ou un multiple de 8.

    NOTE : Allouer 8 bits ici implique que notre élément Pixel Data sera de type (VR) OB. Si on avait mis 16 on aurait dû utiliser le type (VR) OW.

  • Bits Stored (0028,0101) : Sur le nombre de bits alloués, combien de bits sont effectivement utilisés pour représenter l'image. Cette valeur est obligatoirement inférieure ou égale à celle de Bits Allocated. Dans notre cas ça sera 8.

    Prenons un second exemple pour clarifier un peu tout ça. Si on voulait avoir une image avec une profondeur de 12 bits par pixel, dans ce cas on aurait dû définir Bits Allocated à 16 et Bits Stored à 12 (donc on va consommer 16 bits par pixel d'espace dans le fichier, mais il n'y a que 12 bits sur les 16 qui sont utilisés).

  • High Bit (0028,0102) : Numéro du bit le plus significatif. Normalement cette valeur devrait valoir Bit Stored  – 1. Dans notre cas ça sera donc 7.

  • Pixel Representation (0028,0103) : Indique si les nombres utilisés pour représenter les pixels sont signés (complément à 2) ou non signés. Dans notre cas on va utiliser des nombres non signés et donc on stockera 0 dans ce champ.

Voilà comment tout ça se traduit en structures de données :

(7.1-2) Tag VR VL Value (pad?)
Samples per Pixel
Interprétation (0028,0002) US 2 1
Donnée binaire 28 00 02 00 55 53 02 00 01 00  
Photometric Interpretation
Interprétation (0028,0004) CS 12 MONOCHROME2
Donnée binaire 28 00 04 00 43 53 0C 00 4D 4F 4E 4F 43 48 52 4F 4D 45 32 20
Rows
Interprétation (0028,0010) US 2 2
Donnée binaire 28 00 10 00 55 53 02 00 02 00  
Columns
Interprétation (0028,0011) US 2 2
Donnée binaire 28 00 11 00 55 53 02 00 02 00  
Bits Allocated
Interprétation (0028,0100) US 2 8
Donnée binaire 28 00 00 01 55 53 02 00 08 00  
Bits Stored
Interprétation (0028,0101) US 2 8
Donnée binaire 28 00 01 01 55 53 02 00 08 00  
High Bit
Interprétation (0028,0102) US 2 7
Donnée binaire 28 00 02 01 55 53 02 00 07 00  
Pixel Representation
Interprétation (0028,0103) US 2 0 (non signé)
Donnée binaire 28 00 03 01 55 53 02 00 00 00  

Maintenant qu'on a donné toutes les caractéristiques de notre image... il nous reste plus qu'à l'écrire en utilisant un élément Pixel Data (7FE0,0010) :

(7.1-1) Tag VR pad. VL Value (pad?)
Interprétation (7FE0,0010) OB   4
Donnée binaire E0 7F 10 00 4F 42 00 00 04 00 00 00 FF 00 00 FF  

Références utiles :

On recolle tout ensemble...

Si on reprend tout ce qu'on a fait jusqu'à présent (structures de l'entête et du Data Set) et qu'on remet tout dans l'ordre, on arrive au fichier suivant :

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000080  44 49 43 4D 02 00 00 00  55 4C 04 00 7C 00 00 00  DICM....UL..|...
00000090  02 00 01 00 4F 42 00 00  02 00 00 00 00 01 02 00  ....OB..........
000000A0  02 00 55 49 1A 00 31 2E  32 2E 38 34 30 2E 31 30  ..UI..1.2.840.10
000000B0  30 30 38 2E 35 2E 31 2E  34 2E 31 2E 31 2E 32 00  008.5.1.4.1.1.2.
000000C0  02 00 03 00 55 49 06 00  31 2E 32 2E 33 00 02 00  ....UI..1.2.3...
000000D0  10 00 55 49 14 00 31 2E  32 2E 38 34 30 2E 31 30  ..UI..1.2.840.10
000000E0  30 30 38 2E 31 2E 32 2E  31 00 02 00 12 00 55 49  008.1.2.1.....UI
000000F0  08 00 31 2E 32 2E 33 2E  34 00 02 00 13 00 53 48  ..1.2.3.4.....SH
00000100  0A 00 46 4C 4F 5A 7A 20  31 2E 30 20 08 00 08 00  ..FLOZz 1.0 ....
00000110  43 53 16 00 4F 52 49 47  49 4E 41 4C 5C 50 52 49  CS..ORIGINAL\PRI
00000120  4D 41 52 59 5C 41 58 49  41 4C 08 00 16 00 55 49  MARY\AXIAL....UI
00000130  1A 00 31 2E 32 2E 38 34  30 2E 31 30 30 30 38 2E  ..1.2.840.10008.
00000140  35 2E 31 2E 34 2E 31 2E  31 2E 32 00 08 00 18 00  5.1.4.1.1.2.....
00000150  55 49 06 00 31 2E 32 2E  33 00 10 00 10 00 50 4E  UI..1.2.3.....PN
00000160  0E 00 41 6D 61 6E 64 61  5E 52 69 70 6C 65 79 20  ..Amanda^Ripley
00000170  10 00 20 00 4C 4F 04 00  39 33 37 20 28 00 02 00  .. .LO..937 (...
00000180  55 53 02 00 01 00 28 00  04 00 43 53 0C 00 4D 4F  US....(...CS..MO
00000190  4E 4F 43 48 52 4F 4D 45  32 20 28 00 10 00 55 53  NOCHROME2 (...US
000001A0  02 00 02 00 28 00 11 00  55 53 02 00 02 00 28 00  ....(...US....(.
000001B0  00 01 55 53 02 00 08 00  28 00 01 01 55 53 02 00  ..US....(...US..
000001C0  08 00 28 00 02 01 55 53  02 00 07 00 28 00 03 01  ..(...US....(...
000001D0  55 53 02 00 00 00 E0 7F  10 00 4F 42 00 00 04 00  US........OB....
000001E0  00 00 FF 00 00 FF                                ......

Vous pouvez télécharger ce fichier en cliquant sur le bouton ci-dessous :

Et voici ce que ça donne si on ouvre le fichier avec le visualisateur Amide dont je vous avais parlé dans l'article précédent :

Capture d'écran de notre petit DICOM dans Amide (zoom au maximum)

Capture d'écran de notre petit DICOM dans Amide (zoom au maximum)

Bon c'est juste un damier et j'ai dû mettre le zoom au maximum pour qu'on voie quelque chose vu que notre image ne fait que 2×2 px, mais l'essentiel c'est que ça fonctionne ! 😁️

Compléter le fichier à l'aide de DICOM Standard Browser

On vient de créer notre premier fichier DICOM entièrement à la main, c'est cool, mais on a pas tout à fait terminé. En réalité il lui manque des trucs à notre fichier, et d'ailleurs Amide ne se gêne pas pour nous le faire savoir (toujours en train de se plaindre celui-là ! 😛️)  :

Capture d'écran des erreurs remontées par Amide en ouvrant le fichier que l'on vient de créer

Capture d'écran des erreurs remontées par Amide en ouvrant le fichier que l'on vient de créer

Dans le premier article je vous avais mentionné DICOM Standard Browser, un outil permettant de naviguer dans la norme DICOM avec un point de vue orienté sur la pratique... Je vous avais dit qu'on en reparlerait plus longuement eh bah c'est maintenant !

Afin de compléter notre fichier, vous pouvez dès à présent vous rendre sur le site hébergeant l'outil, et je vais vous expliquer comment tout ça fonctionne :

Capture d'écran du DICOM Standard Browser avec la section CT Image dépliée

Capture d'écran du DICOM Standard Browser avec la section CT Image dépliée

Sur la gauche on retrouve une arborescence composée au premier niveau par les différents types d'examens médicaux (CIOD) qui peuvent être stockés dans un fichier DICOM. Pour chacun d'entre eux sont listés les modules qui peuvent être définis pour cet examen. Et pour chaque module on retrouve tous les éléments de données possibles. Pour chaque élément nous est indiqué son tag, le type de la donnée (VR) et s'il est obligatoire ou non (les fameux types 1, 1C, 2, 2C et 3 qu'on avait déjà vus un peu plus tôt).

En cliquant sur un élément, on retrouvera sur la droite un extrait de la documentation (plus ou moins complet en fonction de l'élément) ainsi que des informations utiles et des exemples de valeurs. Plutôt pratique non ? 😎️

Mais ce n'est pas tout, on peut faire encore mieux : il est possible de lui donner un fichier afin de naviguer dedans et voir tout ce qu'il contient... et ce qu'il lui manque ! 😲️

Pour ouvrir un fichier, cliquez sur l'onglet « File Editor » en haut à droite et drag-&-droppez votre fichier DICOM sur la zone prévue à cet effet :

Capture d'écran de l'onglet « File Editor »

Capture d'écran de l'onglet « File Editor »

Une fois le fichier ouvert, DICOM Standard Browser nous affiche un petit résumé du contenu de notre fichier sur la droite, et sur la gauche l'arborescence a pris des couleurs :

  • les éléments qu'on a définis se retrouvent surlignés en orange pâle,
  • et ceux qui sont obligatoires mais qui sont manquants dans le fichier sont surlignés en rouge pâle.
Capture d'écran du DICOM Standard Browser avec notre fichier DICOM en cours d'édition

Capture d'écran du DICOM Standard Browser avec notre fichier DICOM en cours d'édition

Ici on peut voir que 9 attributs obligatoires sont manquants dans notre fichier. Je vous laisse le soin de le compléter si vous le souhaitez. Pour cela vous n'avez qu'à cliquer sur les éléments en rouge pour trouver les attributs manquants et à suivre la documentation intégrée pour trouver comment les remplir !

DICOM Standard Browser est l'un des outils les plus indispensables si vous devez développer un logiciel capable de manipuler des fichiers DICOM.

Conclusion

Et voilà, c'est ainsi que s'achève notre petite virée dans l'univers du DICOM. Au final on s'en fait tout un monde car la norme est juste gigantesque, mais une fois qu'on a les bases et qu'on sait par quel bout la prendre, les choses sont tout de suite plus simples !

Bien qu'on ait abordé qu'une toute petite partie de la norme au cours de cet article en deux parties, j'espère qu'il aura pu vous être utile et vous servir de point de départ si vous avez à manipuler ce type de fichier, ou qu'il vous aura au moins intéressés si vous êtes juste curieux ! En tout cas j'ai essayé d'écrire l'article que j'aurai aimé lire quand je me suis lancé tête baissée dans la norme DICOM ! 😄️

À bientôt pour de nouveaux articles sur de tout autres sujets ! 😁️


L'image de couverture est dérivée d'une image médicale de Nevit Dilmen et est diffusée sous licence CC-BY-SA.