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); }
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--; } } }
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); }
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); }
private static bool IsDicomFile(string filePath) { if (DicomFile.IsDicomFile(filePath)) { return(true); } if (AcrNemaFile.IsAcrNemaFile(filePath)) { return(true); } return(false); }
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); }