Example #1
0
        private AcrNemaFile LoadFile(string filePath)
        {
            AcrNemaFile file = null;

            try
            {
                if (DicomFile.IsDicomFile(filePath))
                {
                    file = new DicomFile(filePath, false);
                }
                else if (AcrNemaFile.IsAcrNemaFile(filePath))
                {
                    file = new AcrNemaFile(filePath, false);
                }
                else
                {
                    Debug.LogError("Selected file is neither a DICOM nor an ACR-NEMA file.");
                }
            }
            catch (Exception dicomFileException)
            {
                Debug.LogError($"Problems processing the DICOM file {filePath} :\n {dicomFileException}");
                return(null);
            }
            return(file);
        }
Example #2
0
        private static void ExtractDataandSave(string folderName, AcrNemaFile file)
        {
            var b = new XmlFile(file, true);

            b.SaveTo(folderName + "//XML_WithoutPD.xml");

            if (!file.HasPixelData)
            {
                return;
            }

            var pixelData = file.PixelData;

            int count = 0;

            foreach (var item in pixelData.ToBytesArray())
            {
                count++;
                try
                {
                    var   ms  = new MemoryStream(item);
                    Image img = Image.FromStream(ms);
                    img.Save(folderName + "//Image" + count + ".jpg");
                    img.Dispose();
                }
                catch
                {
                    count--;
                }
            }
        }
Example #3
0
        private static void PerformExtraction(string filePath)
        {
            AcrNemaFile file;

            if (DicomFile.IsDicomFile(filePath))
            {
                file = new DicomFile(filePath, false);
            }
            else if (AcrNemaFile.IsAcrNemaFile(filePath))
            {
                file = new AcrNemaFile(filePath, false);
            }
            else
            {
                return;
            }

            string filename   = new FileInfo(filePath).Name;
            string fileFolder = Directory.GetParent(filePath) + "\\" + filename + "_dicom";

            if (!Directory.Exists(fileFolder))
            {
                Directory.CreateDirectory(fileFolder);
            }

            ExtractDataandSave(fileFolder, file);
        }
Example #4
0
        private DICOMSliceFile ReadDICOMFile(string filePath)
        {
            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");
                    return(null);
                }
                // 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.");
                }
                // Read pixel spacing
                Tag pixelSpacingTag = new Tag("(0028,0030)");
                if (file.DataSet.Contains(pixelSpacingTag))
                {
                    DataElement elemPixelSpacing = file.DataSet[pixelSpacingTag];
                    slice.pixelSpacing = (float)Convert.ToDouble(elemPixelSpacing.Value[0]);
                }

                return(slice);
            }
            return(null);
        }
Example #5
0
        private static bool IsDicomFile(string filePath)
        {
            if (DicomFile.IsDicomFile(filePath))
            {
                return(true);
            }

            if (AcrNemaFile.IsAcrNemaFile(filePath))
            {
                return(true);
            }

            return(false);
        }
Example #6
0
        private DICOMSliceFile ReadDICOMFile(string filePath)
        {
            AcrNemaFile file = LoadFile(filePath);

            if (file != null && file.HasPixelData)
            {
                DICOMSliceFile slice = new DICOMSliceFile();
                slice.file     = file;
                slice.filePath = filePath;

                Tag locTag          = new Tag("(0020,1041)");
                Tag posTag          = new Tag("(0020,0032)");
                Tag interceptTag    = new Tag("(0028,1052)");
                Tag slopeTag        = new Tag("(0028,1053)");
                Tag pixelSpacingTag = new Tag("(0028,0030)");
                Tag seriesUIDTag    = new Tag("(0020,000E)");

                // Read location (optional)
                if (file.DataSet.Contains(locTag))
                {
                    DataElement elemLoc = file.DataSet[locTag];
                    slice.location = (float)Convert.ToDouble(elemLoc.Value[0]);
                }
                // If no location tag, read position tag (will need to calculate location afterwards)
                else if (file.DataSet.Contains(posTag))
                {
                    DataElement elemLoc = file.DataSet[posTag];
                    Vector3     pos     = Vector3.zero;
                    pos.x                 = (float)Convert.ToDouble(elemLoc.Value[0]);
                    pos.y                 = (float)Convert.ToDouble(elemLoc.Value[1]);
                    pos.z                 = (float)Convert.ToDouble(elemLoc.Value[2]);
                    slice.position        = pos;
                    slice.missingLocation = true;
                }
                else
                {
                    Debug.LogError($"Missing location/position tag in file: {filePath}.\n The file will not be imported correctly.");
                    // Fallback: use counter as location
                    slice.location = (float)iFallbackLoc++;
                }

                // Read intercept
                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
                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.");
                }

                // Read pixel spacing
                if (file.DataSet.Contains(pixelSpacingTag))
                {
                    DataElement elemPixelSpacing = file.DataSet[pixelSpacingTag];
                    slice.pixelSpacing = (float)Convert.ToDouble(elemPixelSpacing.Value[0]);
                }

                // Read series UID
                if (file.DataSet.Contains(seriesUIDTag))
                {
                    DataElement elemSeriesUID = file.DataSet[seriesUIDTag];
                    slice.seriesUID = Convert.ToString(elemSeriesUID.Value[0]);
                }

                return(slice);
            }
            return(null);
        }
        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);
        }