Esempio n. 1
0
        public List <DICOMSeries> LoadDICOMSeries()
        {
            DataElementDictionary dataElementDictionary = new DataElementDictionary();
            UidDictionary         uidDictionary         = new UidDictionary();

            try
            {
                // Load .dic files from Resources
                TextAsset dcmElemAsset = (TextAsset)Resources.Load("dicom-elements-2007.dic");
                Debug.Assert(dcmElemAsset != null, "dicom-elements-2007.dic is missing from the Resources folder");
                TextAsset dcmUidsAsset = (TextAsset)Resources.Load("dicom-uids-2007.dic");
                Debug.Assert(dcmUidsAsset != null, "dicom-uids-2007.dic is missing from the Resources folder");

                dataElementDictionary.LoadFromMemory(new MemoryStream(dcmElemAsset.bytes), DictionaryFileFormat.BinaryFile);
                uidDictionary.LoadFromMemory(new MemoryStream(dcmUidsAsset.bytes), DictionaryFileFormat.BinaryFile);
            }
            catch (Exception dictionaryException)
            {
                Debug.LogError("Problems processing dictionaries:\n" + dictionaryException);
                return(null);
            }

            // Load all DICOM files
            List <DICOMSliceFile> files = new List <DICOMSliceFile>();

            IEnumerable <string> sortedFiles = fileCandidates.OrderBy(s => s);

            foreach (string filePath in sortedFiles)
            {
                DICOMSliceFile sliceFile = ReadDICOMFile(filePath);
                if (sliceFile != null)
                {
                    files.Add(sliceFile);
                }
            }

            // Split parsed DICOM files into series (by DICOM series UID)
            Dictionary <string, DICOMSeries> seriesByUID = new Dictionary <string, DICOMSeries>();

            foreach (DICOMSliceFile file in files)
            {
                if (!seriesByUID.ContainsKey(file.seriesUID))
                {
                    seriesByUID.Add(file.seriesUID, new DICOMSeries());
                }
                seriesByUID[file.seriesUID].dicomFiles.Add(file);
            }

            Debug.Log($"Loaded {seriesByUID.Count} DICOM series");

            return(new List <DICOMSeries>(seriesByUID.Values));
        }
Esempio n. 2
0
        public DicomExtractor(ILogger logger)
        {
            _dataElementDictionary = new DataElementDictionary();
            _uidDictionary         = new UidDictionary();
            _logger = logger;

            string path     = Assembly.GetExecutingAssembly().Location;
            var    fileInfo = new FileInfo(path);
            string dir      = fileInfo.DirectoryName;

            _dataElementDictionary.LoadFrom(dir + "/dicom-elements-2007.dic", DictionaryFileFormat.BinaryFile);

            _uidDictionary.LoadFrom(dir + "/dicom-uids-2007.dic", DictionaryFileFormat.BinaryFile);
        }
Esempio n. 3
0
        public override VolumeDataset Import()
        {
            DataElementDictionary dataElementDictionary = new DataElementDictionary();
            UidDictionary         uidDictionary         = new UidDictionary();

            try
            {
                dataElementDictionary.LoadFrom(Path.Combine(Application.streamingAssetsPath, "dicom-elements-2007.dic"), DictionaryFileFormat.BinaryFile);
                uidDictionary.LoadFrom(Path.Combine(Application.streamingAssetsPath, "dicom-uids-2007.dic"), DictionaryFileFormat.BinaryFile);
            }
            catch (Exception dictionaryException)
            {
                Debug.LogError("Problems processing dictionaries:\n" + dictionaryException);
                return(null);
            }

            // Read all files
            IEnumerable <string> fileCandidates = Directory.EnumerateFiles(diroctoryPath, "*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)
                                                  .Where(p => p.EndsWith(".dcm") || p.EndsWith(".dicom") || p.EndsWith(".dicm"));
            List <DICOMSliceFile> files = new List <DICOMSliceFile>();

            foreach (string filePath in fileCandidates)
            {
                DICOMSliceFile sliceFile = ReadDICOMFile(filePath);
                if (sliceFile != null)
                {
                    files.Add(sliceFile);
                }
            }
            // Sort files by slice location
            files.Sort((DICOMSliceFile a, DICOMSliceFile b) => { return(a.location.CompareTo(b.location)); });

            Debug.Log($"Imported {files.Count} datasets");

            if (files.Count <= 1)
            {
                Debug.LogError("Insufficient number of slices.");
                return(null);
            }

            float minLoc   = (float)files[0].location;
            float maxLoc   = (float)files[files.Count - 1].location;
            float locRange = maxLoc - minLoc;

            // Create dataset
            VolumeDataset dataset = new VolumeDataset();

            dataset.name = Path.GetFileName(Path.GetDirectoryName(diroctoryPath));
            dataset.dimX = files[0].file.PixelData.Columns;
            dataset.dimY = files[0].file.PixelData.Rows;
            dataset.dimZ = files.Count;

            int dimension = dataset.dimX * dataset.dimY * dataset.dimZ;

            dataset.data = new int[dimension];

            for (int iSlice = 0; iSlice < files.Count; iSlice++)
            {
                DICOMSliceFile slice     = files[iSlice];
                PixelData      pixelData = slice.file.PixelData;
                int[]          pixelArr  = ToPixelArray(pixelData);
                if (pixelArr == null) // This should not happen
                {
                    pixelArr = new int[pixelData.Rows * pixelData.Columns];
                }

                for (int iRow = 0; iRow < pixelData.Rows; iRow++)
                {
                    for (int iCol = 0; iCol < pixelData.Columns; iCol++)
                    {
                        int pixelIndex = (iRow * pixelData.Columns) + iCol;
                        int dataIndex  = (iSlice * pixelData.Columns * pixelData.Rows) + (iRow * pixelData.Columns) + iCol;

                        int   pixelValue      = pixelArr[pixelIndex];
                        float hounsfieldValue = pixelValue * slice.slope + slice.intercept;

                        dataset.data[dataIndex] = (int)Mathf.Clamp(hounsfieldValue, -1024.0f, 3071.0f);
                    }
                }
            }

            if (files[0].pixelSpacing > 0.0f)
            {
                dataset.scaleX = files[0].pixelSpacing * dataset.dimX;
                dataset.scaleY = files[0].pixelSpacing * dataset.dimY;
                dataset.scaleZ = Mathf.Abs(files[files.Count - 1].location - files[0].location);
            }

            return(dataset);
        }
        public override VolumeDataset Import()
        {
            DataElementDictionary dataElementDictionary = new DataElementDictionary();
            UidDictionary         uidDictionary         = new UidDictionary();

            try
            {
                dataElementDictionary.LoadFrom(Path.Combine(Application.streamingAssetsPath, "dicom-elements-2007.dic"), DictionaryFileFormat.BinaryFile);
                uidDictionary.LoadFrom(Path.Combine(Application.streamingAssetsPath, "dicom-uids-2007.dic"), DictionaryFileFormat.BinaryFile);
            }
            catch (Exception dictionaryException)
            {
                Debug.LogError("Problems processing dictionaries:\n" + dictionaryException);
                return(null);
            }

            IEnumerable <string> fileCandidates = Directory.EnumerateFiles(diroctoryPath, "*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)
                                                  .Where(p => p.EndsWith(".dcm") || p.EndsWith(".dicom") || p.EndsWith(".dicm"));
            List <DICOMSliceFile> files = new List <DICOMSliceFile>();

            foreach (string filePath in fileCandidates)
            {
                AcrNemaFile file = LoadFile(filePath);
                if (file != null && file.HasPixelData)
                {
                    DICOMSliceFile slice = new DICOMSliceFile();
                    slice.file = file;
                    // Read location
                    Tag locTag = new Tag("(0020,1041)");
                    if (file.DataSet.Contains(locTag))
                    {
                        DataElement elemLoc = file.DataSet[locTag];
                        slice.location = (float)Convert.ToDouble(elemLoc.Value[0]);
                    }
                    else
                    {
                        Debug.LogError($"Missing location tag in file: {filePath}.\n The file will not be imported");
                        continue;
                    }
                    // Read intercept
                    Tag interceptTag = new Tag("(0028,1052)");
                    if (file.DataSet.Contains(interceptTag))
                    {
                        DataElement elemIntercept = file.DataSet[interceptTag];
                        slice.intercept = (float)Convert.ToDouble(elemIntercept.Value[0]);
                    }
                    else
                    {
                        Debug.LogWarning($"The file {filePath} is missing the intercept element. As a result, the default transfer function might not look good.");
                    }
                    // Read slope
                    Tag slopeTag = new Tag("(0028,1053)");
                    if (file.DataSet.Contains(slopeTag))
                    {
                        DataElement elemSlope = file.DataSet[slopeTag];
                        slice.slope = (float)Convert.ToDouble(elemSlope.Value[0]);
                    }
                    else
                    {
                        Debug.LogWarning($"The file {filePath} is missing the intercept element. As a result, the default transfer function might not look good.");
                    }

                    files.Add(slice);
                }
            }
            files.Sort((DICOMSliceFile a, DICOMSliceFile b) => { return(a.location.CompareTo(b.location)); });

            Debug.Log($"Imported {files.Count} datasets");

            if (files.Count <= 1)
            {
                Debug.LogError("Insufficient number of slices.");
                return(null);
            }

            float minLoc   = (float)files[0].location;
            float maxLoc   = (float)files[files.Count - 1].location;
            float locRange = maxLoc - minLoc;

            VolumeDataset dataset = new VolumeDataset();

            dataset.dimX = files[0].file.PixelData.Columns;
            dataset.dimY = files[0].file.PixelData.Rows;
            dataset.dimZ = files.Count;

            int dimension = dataset.dimX * dataset.dimY * dataset.dimZ;

            dataset.data = new int[dimension];

            for (int iSlice = 0; iSlice < files.Count; iSlice++)
            {
                DICOMSliceFile slice     = files[iSlice];
                PixelData      pixelData = slice.file.PixelData;
                int[]          pixelArr  = ToPixelArray(pixelData);
                if (pixelArr == null) // This should not happen
                {
                    pixelArr = new int[pixelData.Rows * pixelData.Columns];
                }

                for (int iRow = 0; iRow < pixelData.Rows; iRow++)
                {
                    for (int iCol = 0; iCol < pixelData.Columns; iCol++)
                    {
                        int pixelIndex = (iRow * pixelData.Columns) + iCol;
                        int dataIndex  = (iSlice * pixelData.Columns * pixelData.Rows) + (iRow * pixelData.Columns) + iCol;

                        int   pixelValue      = pixelArr[pixelIndex];
                        float hounsfieldValue = pixelValue * slice.slope + slice.intercept;

                        dataset.data[dataIndex] = (int)Mathf.Clamp(hounsfieldValue, -1024.0f, 3071.0f);
                    }
                }
            }

            return(dataset);
        }
        public override VolumeDataset Import()
        {
            DataElementDictionary dataElementDictionary = new DataElementDictionary();
            UidDictionary         uidDictionary         = new UidDictionary();

            try
            {
                dataElementDictionary.LoadFrom(Path.Combine(Application.streamingAssetsPath, "dicom-elements-2007.dic"), DictionaryFileFormat.BinaryFile);
                uidDictionary.LoadFrom(Path.Combine(Application.streamingAssetsPath, "dicom-uids-2007.dic"), DictionaryFileFormat.BinaryFile);
            }
            catch (Exception dictionaryException)
            {
                Debug.LogError("Problems processing dictionaries:\n" + dictionaryException);
                return(null);
            }

            List <DICOMSliceFile> files = new List <DICOMSliceFile>();

            foreach (string filePath in Directory.EnumerateFiles(diroctoryPath, "*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
            {
                AcrNemaFile file = LoadFile(filePath);
                if (file != null && file.HasPixelData)
                {
                    DICOMSliceFile slice = new DICOMSliceFile();
                    slice.file = file;
                    DataElement sliceLocElem = file.DataSet[new Tag("(0020,1041)")];
                    slice.location = Convert.ToDouble(sliceLocElem.Value[0]);
                    files.Add(slice);
                }
            }
            files.Sort((DICOMSliceFile a, DICOMSliceFile b) => { return(a.location.CompareTo(b.location)); });

            Debug.Log($"Imported {files.Count} datasets");

            if (files.Count <= 1)
            {
                Debug.LogError("Insufficient number of slices.");
                return(null);
            }

            float minLoc   = (float)files[0].location;
            float maxLoc   = (float)files[files.Count - 1].location;
            float locRange = maxLoc - minLoc;

            VolumeDataset dataset = new VolumeDataset();

            dataset.dimX = files[0].file.PixelData.Columns;
            dataset.dimY = files[0].file.PixelData.Rows;
            dataset.dimZ = files.Count;

            int dimension = dataset.dimX * dataset.dimY * dataset.dimZ;

            dataset.data = new int[dimension];

            for (int iSlice = 0; iSlice < files.Count; iSlice++)
            {
                DICOMSliceFile slice     = files[iSlice];
                PixelData      pixelData = slice.file.PixelData;
                int[]          pixelArr  = ToPixelArray(pixelData);
                if (pixelArr == null) // This should not happen
                {
                    pixelArr = new int[pixelData.Rows * pixelData.Columns];
                }

                for (int iRow = 0; iRow < pixelData.Rows; iRow++)
                {
                    for (int iCol = 0; iCol < pixelData.Columns; iCol++)
                    {
                        int pixelIndex = (iRow * pixelData.Columns) + iCol;
                        int dataIndex  = (iSlice * pixelData.Columns * pixelData.Rows) + (iRow * pixelData.Columns) + iCol;
                        dataset.data[dataIndex] = pixelArr[pixelIndex];
                    }
                }
            }

            /*foreach (openDicom.DataStructure.DataSet.DataElement element in file.DataSet)
             * {
             *  Debug.Log(file.DataSet.StreamPosition);
             *  Debug.Log(element.Tag.ToString() + " - " + element.VR.Tag.GetDictionaryEntry().Description);
             * }*/

            /*
             * dataset.dimX = file.DataSet.GetEnumerator;
             * dataset.dimY = dimY;
             * dataset.dimZ = dimZ;
             *
             * int uDimension = dimX * dimY * dimZ;
             * dataset.data = new int[uDimension];*/

            return(dataset);
        }