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); }
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); }