public static TVEResults Calculate(SliceData sliceData, double factor = 0.3, CalcMode mode = CalcMode.BySum) { var data = mode == CalcMode.BySum ? sliceData.DataBySum : sliceData.DataByCount; var total = data.Sum(x => x); var tve = new TVEResults { SliceData = sliceData, Factor = factor, Total = total, Cutoff = (int)(total * factor), Mode = mode, }; var sorted = data.OrderByDescending(x => x).ToArray(); int sum = 0; int nToExceed = 0; for (int i = 0; i < sorted.Length; i++) { nToExceed++; sum += sorted[i]; if (sum > tve.Cutoff) { break; } } tve.Count = nToExceed; tve.Percentage = nToExceed * 100.0 / sliceData.Count; return(tve); }
public static Histogram Calculate(SliceData sd, CalcMode calcMode = CalcMode.BySum, HistoMode histoMode = HistoMode.Normal) { var h = new Histogram { SliceData = sd, Frequency = new int[100], CalcMode = calcMode, HistoMode = histoMode, }; var data = calcMode == CalcMode.ByCount ? sd.DataByCount : sd.DataBySum; if (h.HistoMode == HistoMode.Normal) { var min = calcMode == CalcMode.ByCount ? sd.RollingCountMinValue : sd.RollingSumMinValue; var max = calcMode == CalcMode.ByCount ? sd.RollingCountMaxValue : sd.RollingSumMaxValue; double div = Math.Max(1.0, max - min); foreach (var val in data) { int idx = Math.Min(99, (int)Math.Floor((val - min) / div * 100.0)); h.Frequency[idx]++; } } else { var min = calcMode == CalcMode.ByCount ? sd.RollingCountMinValue : sd.RollingSumMinValue; var max = calcMode == CalcMode.ByCount ? sd.RollingCountMaxValue : sd.RollingSumMaxValue; double div = Math.Max(10.0, max - min); foreach (var val in data) { int idx = Math.Min(99, (int)Math.Floor((Math.Log10(Math.Max(1, val - min)) / Math.Log10(div) * 100.0))); h.Frequency[idx]++; } } return(h); }
public static SliceData Calculate(RawData raw, double thresholdPercent = 0.1, int rollingWidth = 100) { var sd = new SliceData { RawData = raw, Sums = new int[raw.FrameCount], PixelsAboveThreshold = new int[raw.FrameCount], Mins = new int[raw.FrameCount], Maxs = new int[raw.FrameCount], RollingSums = new int[raw.FrameCount - rollingWidth + 1], RollingCounts = new int[raw.FrameCount - rollingWidth + 1], RollingWidth = rollingWidth, ThresholdPercent = thresholdPercent, Count = rollingWidth * raw.PixelsPerFrame, }; var sorted = raw.Data.OrderByDescending(s => s).ToArray(); sd.MinValue = sorted.Last(); sd.MaxValue = sorted.First(); var nonzero = sorted.Where(s => s > 0).ToArray(); int threshold = nonzero[(int)((1 - thresholdPercent) * nonzero.Length)]; for (int f = 0; f < raw.FrameCount; f++) { int min = int.MaxValue; int max = int.MinValue; int sum = 0; int aboveThreshold = 0; int frameOffset = raw.PixelsPerFrame * f; for (int p = frameOffset; p < frameOffset + raw.PixelsPerFrame; p++) { int val = raw.Data[p]; if (val > max) { max = val; } else if (val < min) { min = val; } sum += val; if (val > threshold) { aboveThreshold++; } } sd.Sums[f] = sum; sd.Mins[f] = min; sd.Maxs[f] = max; sd.PixelsAboveThreshold[f] = aboveThreshold; } // Rolling Sums int rs_sum = 0; for (int i = 0; i < rollingWidth; i++) { rs_sum += sd.Sums[i]; } sd.RollingSums[0] = rs_sum; int rs_max = rs_sum; int rs_maxIndex = 0; for (int i = rollingWidth; i < raw.FrameCount; i++) { rs_sum = sd.RollingSums[i - rollingWidth] - sd.Sums[i - rollingWidth] + sd.Sums[i]; sd.RollingSums[i - rollingWidth + 1] = rs_sum; if (rs_sum > rs_max) { rs_max = rs_sum; rs_maxIndex = i - rollingWidth + 1; } } sd.RollingSumMaxStartIndex = rs_maxIndex; sd.RollingSumMinValue = sd.DataBySum.Min(); sd.RollingSumMaxValue = sd.DataBySum.Max(); // Rolling Counts int rc_sum = 0; for (int i = 0; i < rollingWidth; i++) { rc_sum += sd.PixelsAboveThreshold[i]; } sd.RollingCounts[0] = rc_sum; int rc_max = rc_sum; int rc_maxIndex = 0; for (int i = rollingWidth; i < raw.FrameCount; i++) { rc_sum = sd.RollingCounts[i - rollingWidth] - sd.PixelsAboveThreshold[i - rollingWidth] + sd.PixelsAboveThreshold[i]; sd.RollingCounts[i - rollingWidth + 1] = rc_sum; if (rc_sum > rc_max) { rc_max = rc_sum; rc_maxIndex = i - rollingWidth + 1; } } sd.RollingCountMaxStartIndex = rc_maxIndex; sd.RollingCountMinValue = sd.DataByCount.Min(); sd.RollingCountMaxValue = sd.DataByCount.Max(); return(sd); }
static int Main(string[] args) { var lcArgs = args.Select(arg => arg.ToLower()); if (args.Length == 0 || lcArgs.Any(arg => arg == "/?" || arg == "help")) { Console.WriteLine($"Usage: dotnet {Assembly.GetEntryAssembly().GetName().Name} commands DICOM.file"); Console.WriteLine("Valid commands are: PixelData SliceData Rolling TVEBySum TVEByCount HistoBySum HistoByCount HistoLogBySum HistoLogByCount"); Console.WriteLine("Call with --version to get version info"); return(0); } if (lcArgs.Any(arg => arg == "--version")) { Console.WriteLine(Assembly.GetEntryAssembly().GetName().Version); return(0); } // Check if last arg is a valid file. var path = Path.GetFullPath(args.LastOrDefault() ?? @"\"); FileInfo fileInfo = new FileInfo(path); if (!fileInfo.Exists) { Console.WriteLine("No valid path supplied. Aborting."); return(1); } // Read and parse the DICOM file. var raw = RawData.FromDicom(fileInfo.FullName); if (raw == null) { Console.WriteLine("Failed to parse DICOM file. Aborting."); return(1); } // Output raw pixel data? if (lcArgs.Any(arg => arg == "pixeldata")) { Console.WriteLine(raw.DumpPixelData()); } var sd = SliceData.Calculate(raw); // Output slice data? if (lcArgs.Any(arg => arg == "slicedata")) { Console.WriteLine(sd.Dump()); } // Output rolling data? if (lcArgs.Any(arg => arg == "rolling")) { Console.WriteLine(sd.DumpRolling()); } // Calculate and output TVE by sums? if (lcArgs.Any(arg => arg == "tvebysum")) { var tveSum = TVEResults.Calculate(sd); Console.WriteLine(tveSum.Dump()); } // Calculate and output TVE by counts? if (lcArgs.Any(arg => arg == "tvebycount")) { var tveCount = TVEResults.Calculate(sd, mode: CalcMode.ByCount); Console.WriteLine(tveCount.Dump()); } // Calculate and output histogram data? if (lcArgs.Any(arg => arg == "histobysum")) { var histo = Histogram.Calculate(sd, CalcMode.BySum, HistoMode.Normal); Console.WriteLine(histo.Dump()); } if (lcArgs.Any(arg => arg == "histobycount")) { var histo = Histogram.Calculate(sd, CalcMode.ByCount, HistoMode.Normal); Console.WriteLine(histo.Dump()); } if (lcArgs.Any(arg => arg == "histologbysum")) { var histo = Histogram.Calculate(sd, CalcMode.BySum, HistoMode.Log10); Console.WriteLine(histo.Dump()); } if (lcArgs.Any(arg => arg == "histologbycount")) { var histo = Histogram.Calculate(sd, CalcMode.ByCount, HistoMode.Log10); Console.WriteLine(histo.Dump()); } #if DEBUG Console.ReadKey(); #endif return(0); }