Exemplo n.º 1
0
        /// <summary>
        /// Convert image to color space of known stain.
        /// </summary>
        /// <param name="source">Source image.</param>
        /// <param name="stain">Known stain.</param>
        /// <param name="channel">Channel of stain. Takes int 0-2.</param>
        /// <returns>Color deconvoluted image.</returns>
        public static Bitmap ColorDeconvolution(Bitmap source, ColorDeconvolution.KnownStain stain, int channel)
        {
            using (var image = source.Clone() as Bitmap)
            {
                BitmapProcessor    bitmapProcessor    = new BitmapProcessor(source);
                ColorDeconvolution colorDeconvolution = new ColorDeconvolution();
                GrayscaleProcessor gpDeconvoluted     = null;
                if (channel == 0)
                {
                    gpDeconvoluted = colorDeconvolution.Get1stStain(bitmapProcessor, stain);
                }
                else if (channel == 1)
                {
                    gpDeconvoluted = colorDeconvolution.Get2ndStain(bitmapProcessor, stain);
                }
                else if (channel == 2)
                {
                    gpDeconvoluted = colorDeconvolution.Get3rdStain(bitmapProcessor, stain);
                }
                else
                {
                    return(null);
                }

                Bitmap result = gpDeconvoluted.Bitmap.Clone() as Bitmap;
                gpDeconvoluted.Dispose();
                return(result);
            }
        }
Exemplo n.º 2
0
        private static void Main(string[] args)
        {
            foreach (var slideName in Util.GetSlideFilenames(args))
            {
                using (var slideCache = new SlideCache(slideName)){
                    var hValues = File.Exists(slideCache.DataPath + "hValues.xml")?SlidePartitioner <double> .Load(slideCache.DataPath + "hValues.xml"):new SlidePartitioner <double>(slideCache.Slide, 1f, new Size(2000, 2000));

                    var eValues = File.Exists(slideCache.DataPath + "eValues.xml")?SlidePartitioner <double> .Load(slideCache.DataPath + "eValues.xml"):hValues.Duplicate <double>();

                    var hRange = new Range <double>();
                    var eRange = new Range <double>();
                    foreach (var tile in hValues.Values)
                    {
                        using (Bitmap tileImage = slideCache.Slide.GetImagePart(tile), hImage = tileImage.Clone() as Bitmap, eImage = tileImage.Clone() as Bitmap){
                            var gpH  = new ColorDeconvolution().Get1stStain(hImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
                            var gpE  = new ColorDeconvolution().Get2ndStain(eImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
                            var hSum = 0u;
                            var eSum = 0u;
                            var cnt  = 0;
                            foreach (var grayscalePixel in gpH.Pixels())
                            {
                                hSum += grayscalePixel.V;
                                eSum += gpE.GetPixel(grayscalePixel.X, grayscalePixel.Y);
                                cnt++;
                            }
                            var meanH = (double)hSum / (double)cnt;
                            tile.Data = meanH;
                            hRange.Add(meanH);
                            var meanE = (double)eSum / (double)cnt;
                            eValues[tile.Index].Data = meanE;
                            eRange.Add(meanE);
                            gpH.Dispose();
                            gpE.Dispose();
                            if (slideCache.Slide.GetAnnotationsInArea(tile.SourceArea).Any())
                            {
                                var tileCache = slideCache.GetTileCache(tile.Index);
                                tileCache.SetImage("rgb", tileImage);
                                tileCache.SetImage("h", gpH.Bitmap);
                                tileCache.SetImage("e", gpE.Bitmap);
                            }
                        }
                        Console.WriteLine(slideCache.SlideName + "-" + tile.Index + " done");
                    }
                    var range = new Range <double> {
                        hRange.Minimum, hRange.Maximum, eRange.Minimum, eRange.Maximum
                    };
                    Func <double, Color> toColor = v => {
                        var c = (int)Math.Round(range.Normalize(v) * 255d);
                        return(Color.FromArgb(c, c, c));
                    };
                    slideCache.SetImage("hValues", hValues.GenerateHeatMap(toColor));
                    slideCache.SetImage("eValues", eValues.GenerateHeatMap(toColor));
                    slideCache.SetImage("overview", slideCache.Slide.GetImagePart(0, 0, slideCache.Slide.Size.Width, slideCache.Slide.Size.Height, hValues.Columns, hValues.Rows));
                    hValues.Save(slideCache.DataPath + "hValues.xml");
                    eValues.Save(slideCache.DataPath + "eValues.xml");
                }
            }
        }
Exemplo n.º 3
0
        private IEnumerable <Tuple <Bitmap, string, int> > process()
        {
            using (var source = this.DisplayedImage.Clone() as Bitmap){
                var gspR = new GrayscaleProcessor(source.Clone() as Bitmap, RgbToGrayscaleConversion.JustReds);
                gspR.Dispose();
                yield return(Tuple.Create(gspR.Bitmap, "Red", 128));

                var gpDAB = new ColorDeconvolution().Get2ndStain(source, ColorDeconvolution.KnownStain.HaematoxylinDAB);
                gpDAB.Dispose();
                yield return(Tuple.Create(gpDAB.Bitmap, "DAB", 128));
            }
        }
        public override ProcessResult Execute(ProcessExecutionParams p)
        {
            GrayscaleProcessor gpH = new ColorDeconvolution().Get1stStain(p.Bitmap, ColorDeconvolution.KnownStain.HaematoxylinEosin);

              GrayscaleProcessor gp = new GrayscaleProcessor(p.Bitmap, RgbToGrayscaleConversion.JustReds);

              GrayscaleProcessor gpSobel = (GrayscaleProcessor)gp.Clone();

              new MeanFilter().Execute(gp, new Size(3, 3));

              new SobelEdgeDetector().Execute(gpSobel);

              new MinimumFilter().Execute(gpH, new Size(3, 3));

              new PixelInverter().Execute(gpH);

              ObjectLayer l1stLevel = this.Execute1stLevelSegmentation(gp, gpSobel, gpH);

              float targetArea = this.GetTargetArea(l1stLevel);

              ObjectLayer l2ndLevel = this.Execute2ndLevelSegmentation(gp, gpSobel, gpH, targetArea);

              ObjectLayer l3rdLevel = this.Execute3rdLevelSegmentation(l2ndLevel, gpSobel, gpH, targetArea);

              gpSobel.WriteBack = false;
              gpH.WriteBack = false;
              gp.WriteBack = false;

              gpSobel.Dispose();
              gpH.Dispose();
              gp.Dispose();

              gpSobel.Bitmap.Dispose();
              gpH.Bitmap.Dispose();

              l3rdLevel.Name = "Image Analysis";

              return new ProcessResult(new ObjectLayer[] { l3rdLevel });
        }
        public override ProcessResult Execute(ProcessExecutionParams p)
        {
            GrayscaleProcessor gpH = new ColorDeconvolution().Get1stStain(p.Bitmap, ColorDeconvolution.KnownStain.HaematoxylinEosin);

            GrayscaleProcessor gp = new GrayscaleProcessor(p.Bitmap, RgbToGrayscaleConversion.JustReds);

            GrayscaleProcessor gpSobel = (GrayscaleProcessor)gp.Clone();

            new MeanFilter().Execute(gp, new Size(3, 3));

            new SobelEdgeDetector().Execute(gpSobel);

            new MinimumFilter().Execute(gpH, new Size(3, 3));

            new PixelInverter().Execute(gpH);

            ObjectLayer l1stLevel = this.Execute1stLevelSegmentation(gp, gpSobel, gpH);

            float targetArea = this.GetTargetArea(l1stLevel);

            ObjectLayer l2ndLevel = this.Execute2ndLevelSegmentation(gp, gpSobel, gpH, targetArea);

            ObjectLayer l3rdLevel = this.Execute3rdLevelSegmentation(l2ndLevel, gpSobel, gpH, targetArea);

            gpSobel.WriteBack = false;
            gpH.WriteBack     = false;
            gp.WriteBack      = false;

            gpSobel.Dispose();
            gpH.Dispose();
            gp.Dispose();

            gpSobel.Bitmap.Dispose();
            gpH.Bitmap.Dispose();

            l3rdLevel.Name = "Image Analysis";

            return(new ProcessResult(new ObjectLayer[] { l3rdLevel }));
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
              this.CreateTabContainer("StromaDetection");
              this.TabContainer.Enabled = true;

              (new Button
              {
            Text = "execute cell core segmentation",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.DisplayedImage) return;
            ProcessResult result = null;
            var progressDialog = new ProgressDialog { Message = "executing cell core segmentation", ProgressBarStyle = ProgressBarStyle.Marquee, AllowCancel = false };
            progressDialog.BackgroundTask += () =>
            {
              var segmentation = new CellCoreSegmentation();
              var executionParams = new ProcessExecutionParams(this.DisplayedImage);
              result = segmentation.Execute(executionParams);
            };
            progressDialog.CenterToScreen();
            progressDialog.ShowDialog();
            this.SetLayers(result.Layers.ToArray());
              };

              (new Button
              {
            Text = "execute threshold segmentation",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.DisplayedImage) return;
            var m = new Map(this.DisplayedImage.Width, this.DisplayedImage.Height);
            using (var gp = new GrayscaleProcessor(this.DisplayedImage.Clone() as Bitmap, RgbToGrayscaleConversion.Mean))
            {
              for (var x = 0; x < this.DisplayedImage.Width; x++)
              {
            for (var y = 0; y < this.DisplayedImage.Height; y++)
            {
              m[x, y] = gp.GetPixel(x, y) < this.threshold.Value ? 1u : 0u;
            }
              }
            }
            var layer = new ConnectedComponentCollector().Execute(m);
            layer.Name = "threshold " + this.threshold.Value + " segmentation";
            var layers = this.GetLayers().ToList();
            layers.Add(layer);
            this.SetLayers(layers.ToArray());
              };

              this.threshold = new NumericUpDown
              {
            Parent = new GroupBox
            {
              Parent = this.TabContainer,
              Dock = DockStyle.Top,
              Text = "threshold",
              Height = 40
            },
            Dock = DockStyle.Fill,
            Minimum = 0,
            Maximum = 255,
            Increment = 16,
            Value = 128,
            DecimalPlaces = 0
              };

              (new Button
              {
            Text = "display edges",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            this.SetDisplayedImage(this.edges);
              };

              (new Button
              {
            Text = "execute edge detection",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.stainH || null == this.stainE) return;
            this.responseH = Filtering.ExecuteSobel(this.stainH);
            this.responseE = Filtering.ExecuteSobel(this.stainE);
            var substracted = new double[this.responseH.Size.Width, this.responseH.Size.Height];
            var substractedRange = new Range<double>();
            for (var x = 0; x < this.responseH.Size.Width; x++)
            {
              for (var y = 0; y < this.responseH.Size.Height; y++)
              {
            var value = Math.Max(0, this.responseE.Gradient[x, y] - this.responseH.Gradient[x, y]);
            substracted[x, y] = value;
            substractedRange.Add(value);
              }
            }
            this.nonMaximumSupression = Filtering.ExecuteNonMaximumSupression(substracted, this.responseE.Orientation);
            this.edges = Visualization.Visualize(this.nonMaximumSupression, Visualization.CreateColorizing(substractedRange.Maximum));
            this.SetDisplayedImage(this.edges);
              };

              (new Button
              {
            Text = "display haematoxylin",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            this.SetDisplayedImage(this.stainH);
              };

              (new Button {
            Text = "display eosin",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            this.SetDisplayedImage(this.stainE);
              };

              (new Button {
            Text = "display source",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            this.SetDisplayedImage(this.source);
              };

              (new Button {
            Text = "execute deconvolution",
            Parent = this.TabContainer,
            Dock = DockStyle.Top
              }).Click += delegate
              {
            if (null == this.DisplayedImage) return;
            this.source = this.DisplayedImage;
            var gpE = new ColorDeconvolution().Get2ndStain(this.DisplayedImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
            gpE.Dispose();
            this.stainE = gpE.Bitmap;
            var gpH = new ColorDeconvolution().Get1stStain(this.DisplayedImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
            gpH.Dispose();
            this.stainH = gpH.Bitmap;
            this.SetDisplayedImage(this.stainE);
              };
        }
        public static TissueAnnotationClass ComputeFeatures(TissueAnnotationClass tissueAnnotationOld, Bitmap image)
        {
            using (Bitmap hImage = image.Clone() as Bitmap, eImage = image.Clone() as Bitmap)
            {
                TissueAnnotationClass tissueAnnotation = tissueAnnotationOld.Clone();
                int imageSize = 0;

                //H und E Werte aus Bild ermitteln
                var gpH = new ColorDeconvolution().Get1stStain(hImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
                var gpE = new ColorDeconvolution().Get2ndStain(eImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);

                uint[] hHistogram = new uint[256];
                uint[] eHistogram = new uint[256];


                foreach (var grayscalePixel in gpH.Pixels())
                {
                    imageSize++;
                    hHistogram[grayscalePixel.V]++;
                    eHistogram[gpE.GetPixel(grayscalePixel.X, grayscalePixel.Y)]++;
                }


                //Segmentation aus dem Bild ermitteln
                //Layers erstellen
                var luminaLayer = ObjectLayerCreate.CreateLuminaLayer(image);
                var coresLayer  = ObjectLayerCreate.CreateCoresLayer(image);

                //Features dem layer hinzufügen
                coresLayer =
                    ObjectLayerrUtils.AddFeatureFormFactor(
                        ObjectLayerrUtils.AddFeatureCenterPoint(coresLayer));
                luminaLayer =
                    ObjectLayerrUtils.AddFeatureCoresInNear(
                        ObjectLayerrUtils.AddFeatureFormFactor(luminaLayer), coresLayer);


                //Alle Features ermitteln und in Listen schreiben --> sortiert um anschließend Mid und Avverage auszurechen
                List <uint> hHistogramList = histogramToList(hHistogram);
                List <uint> eHistogramList = histogramToList(eHistogram);

                List <uint> coresSizeList       = ObjectLayerrUtils.GetFeatureValueList(coresLayer, "area");
                List <uint> luminaSizeList      = ObjectLayerrUtils.GetFeatureValueList(luminaLayer, "area");
                List <uint> coresFormFactorList = ObjectLayerrUtils.GetFeatureValueList(coresLayer,
                                                                                        "FormFactorOfContour");

                List <uint> luminaFormFactorWithSize  = new List <uint>();
                List <uint> luminaCoresInNear         = new List <uint>();
                List <uint> luminaCoresInNearWithForm = new List <uint>();
                foreach (var imageObject in luminaLayer.Objects)
                {
                    var coresInNear = imageObject.Features.GetFeatureByName("coresInNear").Value;
                    var formFactor  = imageObject.Features.GetFeatureByName("FormFactorOfContour").Value;
                    var area        = imageObject.Features.GetFeatureByName("area").Value;

                    if (Math.Abs(coresInNear) != 0)
                    {
                        luminaCoresInNear.Add((uint)(area / coresInNear));
                        luminaCoresInNearWithForm.Add((uint)((area * formFactor) / coresInNear));
                    }
                    if (Math.Abs(formFactor) != 0)
                    {
                        luminaFormFactorWithSize.Add((uint)(area / (2 * formFactor)));
                    }
                }
                luminaCoresInNear.Sort();
                luminaCoresInNearWithForm.Sort();
                luminaFormFactorWithSize.Sort();

                //alle Features dem Object hinzufügen
                tissueAnnotation.Q25H  = calcQuantil(hHistogramList, 0.25);
                tissueAnnotation.MeanH = calcQuantil(hHistogramList, 0.5);
                tissueAnnotation.Q75H  = calcQuantil(hHistogramList, 0.75);

                tissueAnnotation.Q25E  = calcQuantil(eHistogramList, 0.25);
                tissueAnnotation.MeanE = calcQuantil(eHistogramList, 0.5);
                tissueAnnotation.Q75E  = calcQuantil(eHistogramList, 0.75);

                if (coresSizeList.Count == 0)
                {
                    tissueAnnotation.CountCores = 0u;
                }
                else
                {
                    tissueAnnotation.CountCores = (uint)(imageSize / coresSizeList.Count);
                }

                if (luminaSizeList.Count == 0)
                {
                    tissueAnnotation.CountLumina = 0u;
                }
                else
                {
                    tissueAnnotation.CountLumina = (uint)(imageSize / luminaSizeList.Count);
                }

                tissueAnnotation.MidCoresSize  = calcMid(coresSizeList);
                tissueAnnotation.MeanCoresSize = calcQuantil(coresSizeList, 0.5);
                tissueAnnotation.Q25CoresSize  = calcQuantil(coresSizeList, 0.25);
                tissueAnnotation.Q75CoresSize  = calcQuantil(coresSizeList, 0.75);

                tissueAnnotation.MidLuminaSize  = calcMid(luminaSizeList);
                tissueAnnotation.MeanLuminaSize = calcQuantil(luminaSizeList, 0.5);
                tissueAnnotation.Q25LuminaSize  = calcQuantil(luminaSizeList, 0.25);
                tissueAnnotation.Q75LuminaSize  = calcQuantil(luminaSizeList, 0.75);


                if (coresSizeList.Count == 0)
                {
                    tissueAnnotation.DensityCores = 0;
                }
                else
                {
                    tissueAnnotation.DensityCores = (uint)(imageSize /
                                                           coresSizeList.Count);
                }

                tissueAnnotation.MidFormFactorCores  = calcMid(coresFormFactorList);
                tissueAnnotation.MeanFormFactorCores = calcQuantil(coresFormFactorList, 0.5);
                tissueAnnotation.Q25FormFactorCores  = calcQuantil(coresFormFactorList, 0.25);
                tissueAnnotation.Q75FormFactorCores  = calcQuantil(coresFormFactorList, 0.75);

                tissueAnnotation.MidFormFactorLuminaWithSize  = calcMid(luminaFormFactorWithSize);
                tissueAnnotation.MeanFormFactorLuminaWithSize = calcQuantil(luminaFormFactorWithSize, 0.5);
                tissueAnnotation.Q25FormFactorLuminaWithSize  = calcQuantil(luminaFormFactorWithSize, 0.25);
                tissueAnnotation.Q75FormFactorLuminaWithSize  = calcQuantil(luminaFormFactorWithSize, 0.75);

                tissueAnnotation.MidDensityLuminaCoresInNear  = calcMid(luminaCoresInNear);
                tissueAnnotation.MeanDensityLuminaCoresInNear = calcQuantil(luminaCoresInNear, 0.5);
                tissueAnnotation.Q25DensityLuminaCoresInNear  = calcQuantil(luminaCoresInNear, 0.25);
                tissueAnnotation.Q75DensityLuminaCoresInNear  = calcQuantil(luminaCoresInNear, 0.75);

                tissueAnnotation.MidDensityFormFactorLuminaCoresInNear  = calcMid(luminaCoresInNearWithForm);
                tissueAnnotation.MeanDensityFormFactorLuminaCoresInNear =
                    calcQuantil(luminaCoresInNearWithForm, 0.5);
                tissueAnnotation.Q25DensityFormFactorLuminaCoresInNear =
                    calcQuantil(luminaCoresInNearWithForm, 0.25);
                tissueAnnotation.Q75DensityFormFactorLuminaCoresInNear =
                    calcQuantil(luminaCoresInNearWithForm, 0.75);

                return(tissueAnnotation);
            }
        }
        private static void Main(string[] args)
        {
            #region init
              if (0 == args.Length)
              {
            Console.WriteLine("no slide name");
            return;
              }
              var slideName = args[0];
              var processinHelper = new Processing(slideName);
              var slide = processinHelper.Slide;
              #endregion init

              TiledProcessInformation<uint[]> haematoxylinHistogram;
              TiledProcessInformation<uint[]> eosinHistogram;

              if (!File.Exists(processinHelper.DataPath + "haematoxylinHistogram.tpi") || !File.Exists(processinHelper.DataPath + "eosinHistogram.tpi"))
              {
            if (!Directory.Exists(processinHelper.DataPath + "deconvolution")) Directory.CreateDirectory(processinHelper.DataPath + "deconvolution");
            var tissueData = TiledProcessInformation<bool>.FromFile(processinHelper.DataPath + "tissueData.tpi");
            haematoxylinHistogram = new TiledProcessInformation<uint[]>(tissueData.Partitioner, tissueData.WsiUri);
            eosinHistogram = new TiledProcessInformation<uint[]>(tissueData.Partitioner, tissueData.WsiUri);
            var partitioner = tissueData.Partitioner;
            var dict = new Dictionary<Point, WsiRect>();
            foreach (var tile in tissueData.Partitioner)
              dict.Add(tissueData.Partitioner.CurrentIndices, tile);
            var stopwatch = new Stopwatch();
            foreach (var tile in partitioner)
            {
              var tissueTile = dict[partitioner.CurrentIndices];
              if (!tissueData[tissueTile]) continue;
              stopwatch.Start();
              using (var tileImage = slide.GetImagePart(tile))
              {
            var hHistogramValue = new uint[256];
            var hValues = new List<double>();
            using (var gpH = new ColorDeconvolution().Get1stStain(tileImage, ColorDeconvolution.KnownStain.HaematoxylinEosin))
            {
              foreach (var intensity in gpH.GetPixels())
              {
                hHistogramValue[intensity]++;
                hValues.Add(intensity);
              }
              haematoxylinHistogram.AddDataToCurrentTile(hHistogramValue);
              gpH.Dispose();
              gpH.Bitmap.Save(processinHelper.DataPath + "deconvolution\\" + partitioner.CurrentIndices + ".h.png");
            }
            var eHistogramValue = new uint[256];
            var eValues = new List<double>();
            using (var gpE = new ColorDeconvolution().Get2ndStain(tileImage, ColorDeconvolution.KnownStain.HaematoxylinEosin))
            {
              foreach (var intensity in gpE.GetPixels())
              {
                eHistogramValue[intensity]++;
                eValues.Add(intensity);
              }
              eosinHistogram.AddDataToCurrentTile(eHistogramValue);
              gpE.Dispose();
              gpE.Bitmap.Save(processinHelper.DataPath + "deconvolution\\" + partitioner.CurrentIndices + ".e.png");
            }
            NumericVector hHistogram = RConnector.Engine.CreateNumericVector(hValues);
            RConnector.Engine.SetSymbol("hHistogram", hHistogram);
            NumericVector eHistogram = RConnector.Engine.CreateNumericVector(eValues);
            RConnector.Engine.SetSymbol("eHistogram", eHistogram);
            var handle = RConnector.StartOutput();
            RConnector.Engine.Evaluate("hist(eHistogram, col=rgb(1,0,0,0.5),xlim=c(0,255), main=\"" + partitioner.CurrentIndices + "\", xlab=\"HE\")");
            RConnector.Engine.Evaluate("hist(hHistogram, col=rgb(0,0,1,0.5), add=T)");
            var output = RConnector.EndOutput(handle);
            output.Save(processinHelper.DataPath + "deconvolution\\histogram" + partitioner.CurrentIndices + ".png");
              }
              stopwatch.Stop();
              Console.WriteLine(partitioner.CurrentIndices + ":" + (stopwatch.ElapsedMilliseconds / 1000d) + "s");
              stopwatch.Reset();
            }
            haematoxylinHistogram.ToFile(processinHelper.DataPath + "haematoxylinHistogram.tpi");
            eosinHistogram.ToFile(processinHelper.DataPath + "eosinHistogram.tpi");
              }
              else
              {
            haematoxylinHistogram = TiledProcessInformation<uint[]>.FromFile(processinHelper.DataPath + "haematoxylinHistogram.tpi");
            eosinHistogram = TiledProcessInformation<uint[]>.FromFile(processinHelper.DataPath + "eosinHistogram.tpi");
              }

              var hRange = new Range<uint>();
              foreach (var tile in haematoxylinHistogram.Partitioner)
              {
            if (null == haematoxylinHistogram[tile]) continue;
            uint sum = 0;
            for (uint i = 0; i < 256; i++)
            {
              sum += haematoxylinHistogram[tile][i] * (255 - i);
            }
            hRange.Add(sum);
              }
              Func<uint[], Color> h2pixel = h =>
              {
            if (null == h) return Color.Gray;
            uint sum = 0;
            for (uint i = 0; i < 256; i++)
            {
              sum += h[i] * (255 - i);
            }
            var ratio = (double)sum / hRange.Maximum;
            return Color.FromArgb(0, 0, (int)Math.Round(255.0 * ratio));
              };
              var eRange = new Range<uint>();
              foreach (var tile in eosinHistogram.Partitioner)
              {
            if (null == eosinHistogram[tile]) continue;
            uint sum = 0;
            for (uint i = 0; i < 256; i++)
            {
              sum += eosinHistogram[tile][i] * (255 - i);
            }
            eRange.Add(sum);
              }
              Func<uint[], Color> e2pixel = e =>
              {
            if (null == e) return Color.Gray;
            uint sum = 0;
            for (uint i = 0; i < 256; i++)
            {
              sum += e[i] * (255 - i);
            }
            var ratio = (double)sum / eRange.Maximum;
            return Color.FromArgb((int)Math.Round(255.0 * ratio), 0, 0);
              };
              using (Bitmap b = haematoxylinHistogram.GenerateHeatMap(h2pixel))
            b.Save(processinHelper.DataPath + "haematoxylinHistogram.png");
              using (Bitmap b = eosinHistogram.GenerateHeatMap(e2pixel))
            b.Save(processinHelper.DataPath + "eosinHistogram.png");
              Console.WriteLine("done");
              Console.ReadKey();
        }
Exemplo n.º 9
0
        private static void processInput()
        {
            int Radius = 2;
              int NoiseLevel = 10;

              Console.WriteLine("Processing Input...");
              foreach (var import in importItems)
              {
            Console.WriteLine();
            Console.WriteLine(import.FileName);

            Console.WriteLine("Slide extrahieren...");
            var processingHelper = new Processing(import.FileName);
            var slide = processingHelper.Slide;

            Console.WriteLine("Ausschnitt aus Slide extrahieren mit originaler Auflösung...");
            int partImageWidth = import.LowerRight.X - import.UpperLeft.X;
            int partImageHeight = import.LowerRight.Y - import.UpperLeft.Y;
            Bitmap partImage = slide.GetImagePart(
              import.UpperLeft.X, import.UpperLeft.Y,
              partImageWidth, partImageHeight,
              partImageWidth, partImageHeight
            );

            #region global tissue detection
            Console.WriteLine("Gewebe suchen und in separatem Layer speichern...");
            var bitmapProcessor = new BitmapProcessor(partImage);
            ObjectLayer overviewLayer = new TissueDetector().Execute(bitmapProcessor, Radius, NoiseLevel);
            bitmapProcessor.Dispose();

            Console.WriteLine("Gewebe-Layer in Ausschnitt zeichnen + speichern...");
            DrawObjectsToImage(partImage, overviewLayer, Color.Black);
            partImage.Save(processingHelper.DataPath + "ImagePartTissue.png");
            #endregion global tissue detection

            #region Deconvolution
            Console.WriteLine("Execute deconvolution 3...");
            var gpX = new ColorDeconvolution().Get3rdStain(partImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
            gpX.Dispose();
            Bitmap gpX_bmp = gpX.Bitmap;
            gpX_bmp.Save(processingHelper.DataPath + "ImagePartColor3.png");

            Console.WriteLine("Execute deconvolution 2...");
            var gpE = new ColorDeconvolution().Get2ndStain(partImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
            gpE.Dispose();
            Bitmap gpE_bmp = gpE.Bitmap;
            gpE_bmp.Save(processingHelper.DataPath + "ImagePartColor2.png");

            Console.WriteLine("Execute deconvolution 1...");
            var gpH = new ColorDeconvolution().Get1stStain(partImage, ColorDeconvolution.KnownStain.HaematoxylinEosin);
            gpH.Dispose();
            Bitmap gpH_bmp = gpH.Bitmap;
            gpH_bmp.Save(processingHelper.DataPath + "ImagePartColor1.png");
            #endregion Deconvolution

            #region execute edge detection
            Console.WriteLine("Execute edge detection...");
            SobelResponse responseH = Filtering.ExecuteSobel(gpH_bmp);
            SobelResponse responseE = Filtering.ExecuteSobel(gpE_bmp);
            var substracted = new double[responseH.Size.Width, responseH.Size.Height];
            var substractedRange = new Range<double>();
            for (var x = 0; x < responseH.Size.Width; x++)
            {
              for (var y = 0; y < responseH.Size.Height; y++)
              {
            var value = Math.Max(0, responseE.Gradient[x, y] - responseH.Gradient[x, y]);
            substracted[x, y] = value;
            substractedRange.Add(value);
              }
            }
            double[,] nonMaximumSupression = Filtering.ExecuteNonMaximumSupression(substracted, responseE.Orientation);
            Bitmap edges = Visualization.Visualize(nonMaximumSupression, Visualization.CreateColorizing(substractedRange.Maximum));
            edges.Save(processingHelper.DataPath + "ImagePartEdges.png");
            #endregion execute edge detection

            exportItems.Add(
              new Ausgabe {
            Identify = import.Identify,
            Result = false,
            Message = "kein Fehler"
              }
            );
              }
        }