Ce tutoriel montre brièvement comment réaliser les opérations les plus communes avec l'aide de la librairie ClearCanvas
ClearCanvas est en fait une société qui se consacre à la création d'applications informatiques open source dans le monde de la santé (http://www.clearcanvas.ca/). Ils ont notamment développé un SDK appelé ClearCanvas SDK qui permet, grossièrement, de traiter les fichiers DICOM.
Il existe plusieurs librairies pour traiter ce genre de fichier, mais ClearCanvas possède plusieurs avantages (un forum actif où on peut poser des questions, un SDK totalement orienté objet fait en C#, un peu de documentation même si c'est vrai qu'ils pourraient faire mieux, etc.).
Le but de ce mini tuto est de donner les premiers pas dans l'utilisation de cette librairie qui est assez complexe (si on télécharge le code source, on constate que la solution possède environ 60 projets !).
DICOM est l'acronyme de Digital Imaging and COmmunications in Medicine qui est traduisible par imagerie et communication numériques en médecine. Il est avant tout un standard de communication et d'archivage en imagerie médicale.
C'est l'ACR (American College of Radiology) et la NEMA (National Electric Manufacturers Association) qui l'ont créé en 1985 dans le but de standardiser les données échangées entre les différents appareils de radiologie. Le site Web officiel du standard peut être visité à cette adresse: http://medical.nema.org/.
Le code suivant montre comment lire un fichier DICOM avec la librairie ClearCanvas.
// Load the file DicomFile file = new DicomFile("00010001.dcm"); file.Load(); // Read some attributes... int age = file.DataSet[DicomTags.PatientsAge].GetInt32(0, -1); string name = file.DataSet[DicomTags.PatientsName].GetString(0, null); DateTime? studyDate = file.DataSet[DicomTags.StudyDate].GetDateTime(0);
Le code suivant montre comment écrire un fichier DICOM avec la librairie ClearCanvas.
// Load the file DicomFile file = new DicomFile("00010001.dcm"); file.Load(); // Write some attributes... file.DataSet[DicomTags.PatientsAge].SetInt32(0, 27); file.DataSet[DicomTags.PatientsName].SetString(0, "Anonymous"); file.DataSet[DicomTags.StudyDate].SetDateTime(0, DateTime.Now); // Save file.Save();
Comment customiser un ImageSop, dans ce cas pour passer directement par la mémoire sans se servir d'un fichier temporaire.
public class VSDMImageSop : ImageSop { public VSDMImageSop(string filename) : base(new DicomFile(filename)) { } public VSDMImageSop(DicomFile dicomFile) : base(dicomFile) { } #region Properties public string Filename { get { return DicomFile.Filename; } } private DicomFile DicomFile { get { return NativeDicomObject as DicomFile; } } #endregion protected override void EnsureLoaded() { if (!String.IsNullOrEmpty(this.Filename)) DicomFile.Load(DicomReadOptions.Default | DicomReadOptions.StorePixelDataReferences); } }
Comment extraire une image d'un fichier DICOM
public static class ImageExtractor { public static byte[] ExtractBitmap(string filename) { return ExtractBitmap(new VSDMImageSop(filename)); } public static byte[] ExtractBitmap(DicomFile file) { return ExtractBitmap(new VSDMImageSop(file)); } private static byte[] ExtractBitmap(ImageSop sop) { byte[] b = null; try { Bitmap bitmap = null; MemoryStream ms = new MemoryStream(); IEnumerable<IPresentationImage> images = PresentationImageFactory.Create(sop); // This loop is only needed if we want to get all images.... foreach (IPresentationImage image in images) { ISpatialTransformProvider spatial = image as ISpatialTransformProvider; spatial.SpatialTransform.Scale = 2; bitmap = image.DrawToBitmap(512, 512); bitmap.Save(ms, ImageFormat.Png); break; // Take just the first image ... } // Dispose objects bitmap.Dispose(); bitmap = null; b = ms.ToArray(); ms.Dispose(); ms = null; } catch(Exception ex) { b = null; } return b; } }
Oui je sais, ce n'est pas grand-chose, mais quand il faut chercher ce genre d'informations (qui ne cours pas les rues pour une librairie autant spécifique), ça prend vite beaucoup de temps...