[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