Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }