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