[Dcmlib] gdcm proposal

Mathieu Malaterre mathieu.malaterre at kitware.com
Fri Apr 29 17:02:15 CEST 2005


Je vais essayer de repondre que sur les differences pour eviter 
d'alourdir le mail.

Benoit Regrain wrote:
> Je crois qu'il y a eu confusion dans la compréhension de Document.
> Pour moi, Document, c'est le contenu Dicom (donc une donnée qui equivaudrait
> à un vtkImageData).
> Pour Mathieu, il semble que c'etait plutot la partie Reader/Writer.
> Ce qui je crois amene des confusions dans les reponses aux questions.

Document:
    Representation direct du fichier DICOM
    Idealement il ne charge pas les bin etrny > 4-96
    Mais: si je fais GetEntry(0x7fe0,0010) il est capable (ala VTK) de 
recharcher le fichier pour me retourner l'entree binaire (flux non decode)
    L'utilisation de cette classe est en gros pour permettre a l'util a 
acceder a des custom entry (genre Hopital Name ... )

Image: (ou ImageInterpreter)
    Prend en entree un Document
    Retourne un volume proprement decompresser/reorganiser
    Il sait acceder au champ 7fe0 , il devrait echouer sur un Document
    qui n'a pas cette entry.


La separation de ces classes permet de separer Information (light data) 
de l'Image (Heavy Data). En admettant avoir un pipeline ala VTK, ca 
permet de constuire une mini app qui ne fais qu'afficher les 
informations d'une image DICOM. Ca laisse aussi la possibilite a un util 
de manipuler le volume RAW directement si ca lui chante. Et cela tout en 
laissant la possibilite a un utilisateur de construire une Image pour 
son viewer a partir d'un Document lu.

Je tiens a cette separation dans le future je voudrais d'autre type 
d'interpreter:

OverlayInterpreter:
    Prend un Document en Entree
    Retourn un Overlay (une image 2D je suppose)

StringInterpreter et VectorDoubleInterperter VectorIntInterpretre sont 
un peu different des Interpeter au dessus. Ca serait plus pour python ou 
on pourrait renvoyer un type python (list) a partir d'une chaine separer 
par des \.


> Je crois qu'il faut commencer à donner des noms correct. Voici ce que je 
> propose
> (je ne prefixe pas de gdcm pour ne pas alourdir les choses) :

ok

> DocEntry : comme le DocEntry actuel (contient gr|elem + VR + value)
>                  dérivé en ValEntry, BinEntry, SeqEntry
> SQItem : comme le SQItem actuel, données contenant une liste de DocEntry.

beurk, pourquoi une liste?  je veux mon acces en O(1) garanti -ou 
presque- de partout. Faut que je vois avec brad, mais pour moi on doit 
pouvoir avoir une hash<string, hash<string, DocEntry>>


> Document : données contenant une liste de DocEntry.
>                   gère une image Dicom. Contient des méthodes facilitant 
> l'accès aux
>                   informations de l'image : taille, spacing, origin, 
> orientation, etc.

non. Document c'est vraiment l'image DICOM. Si le spacing est code sur 3 
float, il me renvoi cette chaine de caractere. Il ne sait pas 
interpreter la notion de spacing. Pourquoi mettre un spacing ici alors 
que DicomDir derive de Document ...

> DicomDir : données contenant une arborescence
>                  DicomDirPatient / DicomDirStudy / DicomDirSerie / 
> DicomDirImage
>                  (qui sont aussi des données dérivant de SQItem)
> Image : donnée image Dicom décompressée + Document ?

je vous laisse DicomDir faut que je lise la norme la dessus.

> Reader : traitement qui permet de lire un fichier au format Dicom
> DocReader : traitement qui permet de lire un fichier Dicom contenant un 
> Document
>                        retourne un Document
>                       derive de Reader
> DicomDirReader : traitement qui permet de lire un fichier Dicom 
> contenant un DicomDir
>                       retourne un DicomDir
>                       derive de Reader


Pour moi un DicomDir derive de Document donc dans les deux cas, le 
reader renvoi un Document

> Writer : traitement qui permet d'ecrire un fichier au format Dicom
> DocWriter : traitement qui permet d'ecrire un fichier au format Dicom à 
> partir d'un Document
> DicomV3Writer : traitement qui permet d'ecrire un fichier au format DicomV3
>                       prend un Document en entrée    
>                       derive de DocWriter
> LibidoWriter : traitement qui permet d'ecrire un fichier au format Libido
>                       prend un Document en entrée    
>                       derive de DocWriter
> AcrNemaWriter : traitement qui permet d'ecrire un fichier au format ACR-NEMA
>                       prend un Document en entrée    
>                       derive de DocWriter
> DicomDirWriter : traitement qui permet d'ecrire un fichier au format 
> Dicom à partir d'un DicomDir
>                       prend un DicomDir en entrée    
>                       derive de Writer

ok

> DocValidator : traitement qui verifie la structure d'un Document
>                       prend un Document en entrée
>                       retourne du texte

retourne un Document valide. produit du texte (dans un log?). Ce que tu 
veux vraiment c'est etre sur que tu ecrives ton spacing sur 2 float...

> DicomDirValidator : traitement qui verifie la structure d'un DicomDir
>                       prend un DicomDir en entrée
>                       retourne du texte

idem, produit un Document valide

> SerieOrder : traitement ordonnant une serie de Document
>                      prend une liste de Document en entrée
>                      retourne l'ordre de ces documents (sous quelle forme ?)

prend en entree un filepath d'un repertoire.
retourne une liste de fichiers (vector<string>), qui est passer a un 
SerieReader.


Je tiens a tout prix a cette separation, l'utilisateur doit a tout 
moment lire ces fichiers dans l'order qu'il veut (cas ou les 
heuristiques de SewrieOrder, mais l'utili lui seul sait dans quel order 
les lire).

Maintenant pour les gens qui craignent de lire plusieurs fois la meme 
image et que performance reason blabla... j'ai pas de solution tout 
faite a presenter. J'aimerais etudier un peu plus la notion de parser vs 
reader en XML. J'aimerais -je sais pas si c possible- avoir un mini 
parser qui ne lise qu'un nombre restreint de tag (ImagePosition, 
ImageOrientation, UID et qui sache s'arreter des qu'il les a trouver).

> Decompress : traitement decompressant l'image d'un Document
>                      prend un Document en entrée
>                      retourne une Image
> Document2DicomDirImage : tranforme un Document en DicomDirImage
>                      prend un Document en entrée
>                      retourne un DicomDirImage
> DicomDirImage2Document : tranforme un DicomDirImage en Document
>                      prend un DicomDirImage en entrée
>                      retourne un Document

je vous laisse ca.

> On voit donc apparaitre une dérivation comme suit (incomplète bien sur) :
> Data
>  - Document
>  - DicomDir
>  - Image
> Process
>  - Reader
>     - DicomDirReader
>     - DocReader
>  - Writer
>     - DicomDirWriter
>     - DocWriter
>        - DicomV3Writer
>        - LibidoWriter
>        - DicomV3Writer
>  - Validator
>     - DicomDirValidator
>     - DocValidator
>  - SerieOrder
>  - Decompress
>  - Document2DicomDirImage
>  - DicomDirImage2Document


Base (Print)
  - Document (== ElementSet)
    - DicomDir
  - Image
Process
  - Reader
     - DicomDirReader
     - DocReader
        - DicomV3Reader
          - BustedSiemens
          - BustedGE (13 length hack)
        - LibidoReader
        - ACRNemaReader
  - Writer
     - DicomDirWriter
     - DocWriter
        - DicomV3Writer
        - LibidoWriter
        - ACRWriter
  - Validator
     - DicomDirValidator
     - DocValidator
  - SerieOrder
  - Interpeter
    - ImageInterperter (7fe0)
    - OverlayInterpeter

J'introduis les sous class BustedSiemens et BustedGE, en theorie si on 
ne travaille que sur des IRM philips on ne devrait pas avoir a traiter 
ces cas vraiment particulier. J'aimerais garder l'archi gdcm propre de 
ces hack et laisser a l'util le choix de ne pas compiler ces sous classes...


>  
> Si j'ai bien tout compris, Mathieu, on aura une séparation données 
> traitements (comme dans VTK).
> Ceci n'est bien sur qu'une ebauche, s'appuyant sur ce qui fonctionne 
> deja et les morceaux à changer.
> L'arborescence n'est pas complète, et il y a peut etre des choses 
> fausses ou a revoir.
> Mais une question se pose avec cela... on fait comme dans VTK avec un 
> pipeline mis a jour automatiquement
> ou pas ? Comment on gere les sorties, comme en VTK avec la meme sortie a 
> chaque fois ou avec une
> nouvelle sortie ? Et quand le traitement est détruit, qui détruit la 
> sortie ?
> Désolé de ne parler que de VTK, je ne connais pas encore ITK (mais c'est 
> pour bientot)

Les differences sont minimes si tu compares ITK a VTK < 4.4 (VTK CVS a 
un nouveau pipeline nettement plus complexe).
Pour faire encore comme VTK j'aimerais la notion de reference conting 
dans gdcm.Base. Ca pemettrait de passe le gdcm.Document du reader a 
gdcm.ImageInterpreter sans se soucier de la redundance.

>  
> Ce qui me plait pas dans ce que je viens de présenter (et vi, on peut 
> faire des choses pas belles des
> le début...) c'est la différence entre Document et DicomDirImage... ce 
> qui nous oblige apres a avoir
> des passerelles entre les 2. Mais d'un autre coté, c'est justifiable sur 
> le fait que les deux n'ont pas
> tout en commun... mais la question va etre : pourquoi ne pas dire qu'un 
> DicomDirImage est un Document ?

EXACT !!!! C'est la meme chose c'est un ensemble qui associe une valeur 
a une clef, c'est tout. Ensuite c'est le role de gdcm.Interpreter de 
faire un abort()/reboot() si on lui passe un Document qui est en fait un 
DicomDir...

> et bien tout simplement car dans le DicomDirImage (actuel), on n'a que 
> les champs correspondant au
> niveau image du DicomDir, le DicomDirSerie contenant les info de la 
> serie, idem avec Study et Patient.
> Or, le Document doit contenir toutes les infos de chaque niveau du 
> DicomDir (Patient + Study + Serie + Image).
> Avoir ces convertisseurs obligerait aussi a pouvoir remonter de l'Image 
> jusqu'au Patient, ce qui n'est pas le cas
> actuellement (mais rien empeche de le faire ;-) )

Ok la je suis perdu. C'est ou la description de DicomDir ?

Merci
Mathieu



More information about the Dcmlib mailing list