Introduction
This tutorial briefly shows how to perform the most common operations with the help of the ClearCanvas library.
ClearCanvas is an open source code base for enabling software innovation in medical imaging. The extensible and robust platform includes viewing, archiving, management, workflow and distribution of medical images as well as an open architecture for core competency tool development.
ClearCanvas is actually a company dedicated to creating open source computing applications in the healthcare world. (www.clearcanvas.ca/). In particular, they developed an SDK called ClearCanvas SDK that allows, roughly, to process DICOM files.
There are several libraries to handle this kind of file, but ClearCanvas has several advantages (an active forum where you can ask questions, a completely object-oriented SDK done in C#, some documentation even if it’s true that they could do better, etc.).
The goal of this mini tutorial is to give the first steps in the use of this library is quite complex.
Github repository download address here: https://clearcanvas.github.io/
What is A DICOM File?
DICOM is the acronym for Digital Imaging and Communications in Medicine which is translatable by digital imaging and communication in medicine. It is above all a standard of communication and archiving in medical imaging.
It was the ACR (American College of Radiology) and the National Electric Manufacturers Association (NEMA) that created it in 1985 to standardize the data exchanged between different radiology devices. The official website of the standard can be visited at this address: (medical.nema.org/).
Read a DICOM File
The following code shows how to read a DICOM file with the ClearCanvas library.
1 2 3 4 5 6 7 8 9 10 |
// 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); |
Write a DICOM File
The following code demonstrates how to write a DICOM file with the ClearCanvas library.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 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(); |
Customize an IMAGESOP
How to customize an ImageSop, in this case to go directly through the memory without using a temporary file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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); } } |
Extract an Image From a File
How to extract an image from a DICOM file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
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; } } |
To Finish
Yes I know, it’s not much, but when you have to look for this kind of information (which does not run the streets for a bookstore as specific), it takes a lot of time …