Ejemplo n.º 1
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");
                }
            }
        }
        private static void DrawHeatMapAll(SlidePartitioner <Dictionary <String, TissuAnnotaionEnum> > tissueSlidePartitioner, SlideCache slideCache)
        {
            Func <Dictionary <String, TissuAnnotaionEnum>, Color> drawWekaClassificationBaggingFunc = classifyDic => TissuAnnotaionToColor(classifyDic["wekaClassifyBagging"]);
            Func <Dictionary <String, TissuAnnotaionEnum>, Color> drawOwnClassificationJ48Func      = classifyDic => TissuAnnotaionToColor(classifyDic["ownClassificationJ48"]);
            Func <Dictionary <String, TissuAnnotaionEnum>, Color> drawOwnClassificationJRipFunc     = classifyDic => TissuAnnotaionToColor(classifyDic["ownClassifyJRip"]);

/*            using (var heatMap = tissueSlidePartitioner.GenerateHeatMap(drawWekaClassificationBaggingFunc))
 *          {
 *              slideCache.SetImage("ClassificationDetection_wekaClassifyBagging", heatMap);
 *          }*/
            using (var heatMap = tissueSlidePartitioner.GenerateHeatMap(drawOwnClassificationJ48Func))
            {
                slideCache.SetImage("ClassificationDetection_ownClassifyJ48", heatMap);
            }
            using (var heatMap = tissueSlidePartitioner.GenerateHeatMap(drawOwnClassificationJRipFunc))
            {
                slideCache.SetImage("ClassificationDetection_ownClassifyJRip", heatMap);
            }
        }
        private static void Main(string[] args)
        {
            foreach (var slideName in Util.GetSlideFilenames(args))
            {
                using (var slideCache = new SlideCache(slideName)){
                    var scale    = 0.2f;
                    var tileSize = 200;
                    var slidePartitionerFileName = slideCache.DataPath + "BudDetection.Tissue.xml";
                    var slidePartitioner         = File.Exists(slidePartitionerFileName)?SlidePartitioner <bool?> .Load(slidePartitionerFileName):new SlidePartitioner <bool?>(slideCache.Slide, scale, new Size(tileSize, tileSize));

                    using (var overViewImage = slideCache.Slide.GetImagePart(0, 0, slideCache.Slide.Size.Width, slideCache.Slide.Size.Height, slidePartitioner.Columns, slidePartitioner.Rows)){
                        slideCache.SetImage("overview", overViewImage);                       //speichert unter C:\ProgramData\processingRepository\[slideCache.SlideName]\...
                        //ggf. heatmap hier erstellen
                    }
                    int    i       = 0;
                    int    max     = slidePartitioner.Count;
                    double percent = 0;
                    foreach (var tile in slidePartitioner.Values)
                    {
                        percent = 100.0 * i++ / max;
                        if (tile.Data.HasValue)
                        {
                            Console.WriteLine(slideCache.SlideName + "-" + tile.Index + ":" + tile.Data.Value + " skipped " + percent + "%");
                            continue;
                        }
                        using (var tileImage = slideCache.Slide.GetImagePart(tile)){
                            if (false)
                            {
                                var tileCache = slideCache.GetTileCache(tile.Index);
                                tileCache.SetImage("rgb", tileImage);                               //speichert unter C:\ProgramData\processingRepository\[slideCache.SlideName]\[Index]\... ansonsten tileImage.Save("[uri].png")
                            }
                            var r = BudDetection.MyColorDeconvolution.Execute(tileImage);
                            tile.Data = r.Value;                          //Wert zur Kachel speichern
                        }
                        Console.WriteLine(slideCache.SlideName + "-" + tile.Index + " done " + percent + "%");
                        if (Console.KeyAvailable)
                        {
                            break;
                        }
                    }

                    slidePartitioner.Save(slidePartitionerFileName);
                    using (var heatMap = slidePartitioner.GenerateHeatMap(b => b.HasValue?(b.Value?Color.Green:Color.White):Color.Black)) slideCache.SetImage("tissueHeatMap", heatMap);
                }
            }
        }
Ejemplo n.º 4
0
        private static void Main(string[] args)
        {
            const double GRENZ_ENTROPIE = 0.1;

            foreach (var slideName in Util.GetSlideFilenames(new string[] { args[0] }))
            {
                using (var slideCache = new SlideCache(slideName)){
                    // scale=1 -> baselayer , sollte so klein wie möglich sein um die Rechenzeit zu minimieren
                    // targetSize Größe der zu prozessierenden Bilder, hängt von der hardware ab und bestimmt die Auflösung der Heatmap, für niedrige scale-Werte sollte auch die Größe reduziert werden
                    // Auflösung: Breite=tissueSlidePartitioner.Columns Höhe=tissueSlidePartitioner.Rows
                    // var: implizit typisiert, tatsächlich stark typisiert da der Compiler den Typ kennt; RMT->Goto To Definition
                    // Empfehlung: http://shop.oreilly.com/product/0636920040323.do die 5.0 gibt es auch als pdf im Internet
                    var tissueSlidePartitioner = new SlidePartitioner <bool>(slideCache.Slide, 0.2f, new Size(500, 500)); //Nicht unbedingt auf dem Baselayerr arbeiten zB. 1f --> 0.1
                    using (var overViewImage = slideCache.Slide.GetImagePart(0, 0, slideCache.Slide.Size.Width, slideCache.Slide.Size.Height, tissueSlidePartitioner.Columns, tissueSlidePartitioner.Rows)){
                        //TODO falls die Gewebeerkennung auf dem Übersichtsbild stattfinden soll, dann hier
                        slideCache.SetImage("overview", overViewImage);                       //speichert unter C:\ProgramData\processingRepository\[slideCache.SlideName]\...
                    }

                    //Multithreading
                    Parallel.ForEach(tissueSlidePartitioner.Values, (tile) =>
                    {
                        using (var tileImage = slideCache.Slide.GetImagePart(tile))
                        {
                            var containsTissue = false;
                            double entropie    = 0.0;
                            #region hier sollte containsTissue richtig bestimmt werden
                            var bitmapProcessor = new BitmapProcessor(tileImage);//liefert schnelleren Zugriff auf die Pixel-Werte, alternativ auch SharpAccessory.Imaging.Processors.GrayscaleProcessor

                            int[] greyArray = new int[256];

                            for (var y = 0; y < bitmapProcessor.Height; y++)
                            {
                                for (var x = 0; x < bitmapProcessor.Width; x++)
                                {
                                    var r = bitmapProcessor.GetRed(x, y);
                                    var g = bitmapProcessor.GetGreen(x, y);
                                    var b = bitmapProcessor.GetBlue(x, y);

                                    var grauwert = (int)(r + g + b) / 3;
                                    greyArray[grauwert]++;
                                }
                            }
                            bitmapProcessor.Dispose();

                            //Calculate Shannon Entropie
                            entropie = calcEntropie(greyArray);

                            //Contains Tissue ermitteln
                            if (0 == tile.Index.Y)
                            {
                                containsTissue = false;//oberste Reihe sollte kein Gewebe enthalten
                            }
                            else
                            {
                                //if (slideCache.Slide.GetAnnotationsInArea(tile.SourceArea).Any()) containsTissue = true;//Kacheln mit Annotationen enthalten Gewebe
                                if (entropie > GRENZ_ENTROPIE)
                                {
                                    containsTissue = true;
                                }
                            }
                            #endregion

                            //Wert zur Kachel speichern
                            tile.Data = containsTissue;

                            //Only for Debug
                            var saveImage = false;
                            if (saveImage)
                            {
                                string path = args[1] + @"\" + slideCache.SlideName + @"\";
                                if (containsTissue)
                                {
                                    path += @"isTissue\";
                                }
                                else
                                {
                                    path += @"noTissue\";
                                }

                                if (!Directory.Exists(path))
                                {
                                    Directory.CreateDirectory(path);
                                }
                                tileImage.Save(path + tile.Index.X + "-" + tile.Index.Y + ".png");
                                //var tileCache = slideCache.GetTileCache(tile.Index);
                                //tileCache.SetImage("rgb",tileImage);//speichert unter C:\ProgramData\processingRepository\[slideCache.SlideName]\[Index]\... ansonsten tileImage.Save("[uri].png")
                            }
                            Console.WriteLine(slideCache.SlideName + "-" + tile.Index + " done - containsTissue: " + containsTissue.ToString() + " - entropie: " + entropie.ToString());
                        }
                    });
                    //true wird zu grün, false zu rot; syntax ist lambda (=>) mit einem conditional operator (?)
                    Func <bool, Color> f = b =>
                    {
                        if (b)
                        {
                            return(Color.Red);
                        }
                        else
                        {
                            return(Color.Green);
                        }
                    };
                    using (var heatMap = tissueSlidePartitioner.GenerateHeatMap(f))
                    {
                        slideCache.SetImage("tissueHeatMap", heatMap);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        private static void Main(string[] args)
        {
            Console.WriteLine("Start SlideProzessor");
            Console.WriteLine(args);

            foreach (var slideName in Util.GetSlideFilenames(args))
            {
                Console.WriteLine("progress: " + slideName);

                using (var slideCache = new SlideCache(slideName)){
                    // Skalierung des Bildes
                    var scale    = 0.5f; // 0.1
                    var tileSize = 100;  // 100

                    // Partionierung und speichern
                    var slidePartitionerFileName = slideCache.DataPath + "BudDetection.Tissue.xml";
                    var slidePartitioner         = File.Exists(slidePartitionerFileName)?SlidePartitioner <bool?> .Load(slidePartitionerFileName):new SlidePartitioner <bool?>(slideCache.Slide, scale, new Size(tileSize, tileSize));

                    using (var overViewImage = slideCache.Slide.GetImagePart(0, 0, slideCache.Slide.Size.Width, slideCache.Slide.Size.Height, slidePartitioner.Columns, slidePartitioner.Rows)){
                        slideCache.SetImage("overview", overViewImage);                       //speichert unter C:\ProgramData\processingRepository\[slideCache.SlideName]\...
                        //ggf. heatmap hier erstellen
                    }

                    // über alle Kacheln
                    var counter = 0;
                    foreach (var tile in slidePartitioner.Values)
                    {
                        counter = counter + 1;

                        // ist bereits ein wert vorhanden, dann überspringen
                        if (tile.Data.HasValue)
                        {
                            if (counter % 100 == 0)
                            {
                                Console.WriteLine(slideCache.SlideName + "-" + tile.Index + ":" + tile.Data.Value + " skipped");
                            }
                            continue;
                        }

                        // bitmap erzeugen aus der Kachel
                        using (var tileImage = slideCache.Slide.GetImagePart(tile)){
                            // für debugging zwecke
                            if (false)
                            {
                                var tileCache = slideCache.GetTileCache(tile.Index);
                                tileCache.SetImage("rgb", tileImage);                               //speichert unter C:\ProgramData\processingRepository\[slideCache.SlideName]\[Index]\... ansonsten tileImage.Save("[uri].png")
                            }

                            // Wert Berechnung
                            var r = BudDetection.ColorDeconvolution.Execute(tileImage);
                            tile.Data = r.Value;                           //Wert zur Kachel speichern
                        }

                        if (counter % 100 == 0)
                        {
                            Console.WriteLine(slideCache.SlideName + "-" + tile.Index + " done");
                        }

                        // unterbrechbar via key eingabe
                        if (Console.KeyAvailable)
                        {
                            break;
                        }
                    }

                    // zustand der bearbeitng speichern
                    slidePartitioner.Save(slidePartitionerFileName);
                    using (var heatMap = slidePartitioner.GenerateHeatMap(b => b.HasValue?(b.Value?Color.Green:Color.White):Color.Black)) slideCache.SetImage("tissueHeatMap", heatMap);
                }
            }
        }
Ejemplo n.º 6
0
        private static void Main(string[] args)
        {
            foreach (var slideName in Util.GetSlideFilenames(args))
            {
                using (var slideCache = new SlideCache(slideName)){
                    var scale    = 0.5f;
                    var tileSize = 500;
                    var slidePartitionerFileName = slideCache.DataPath + "BudDetection.Buds.xml";
                    var slidePartitioner         = File.Exists(slidePartitionerFileName)?SlidePartitioner <int?>
                                                   .Load(slidePartitionerFileName):new SlidePartitioner <int?>(slideCache.Slide, scale, new Size(tileSize, tileSize));

                    var heatMapHelper = new HeatMapHelper(slideCache.GetImage("tissueHeatMap"));
                    var budCountRange = new Range <int>();

                    foreach (var tile in slidePartitioner.Values)
                    {
                        if (tile.Data.HasValue)
                        {
                            Console.WriteLine(slideCache.SlideName + "-" + tile.Index + ":" + tile.Data.Value + " skipped");
                            budCountRange.Add(tile.Data.Value);
                            continue;
                        }

                        var colors = heatMapHelper.GetAffectedColors(slideCache.Slide.Size, tile.SourceArea);
                        var values = heatMapHelper.GetAffectedValues(slideCache.Slide.Size, tile.SourceArea);
                        if (values.All(v => 0 != v))
                        {
                            Console.WriteLine(slideCache.SlideName + "-" + tile.Index + ": no tissue");
                            continue;
                        }

                        using (var tileImage = slideCache.Slide.GetImagePart(tile)){
                            if (false)
                            {
                                var tileCache = slideCache.GetTileCache(tile.Index);
                                tileCache.SetImage("rgb", tileImage);                               //speichert unter C:\ProgramData\processingRepository\[slideCache.SlideName]\[Index]\... ansonsten tileImage.Save("[uri].png")
                            }
                            var r = BudDetection.Detector.Execute(tileImage);
                            //var r = ColorDeconvolution.Detect(tileImage);
                            var layer = r.Value;
                            tile.Data = layer.Objects.Count;
                            budCountRange.Add(layer.Objects.Count);
                            foreach (var io in layer.Objects)
                            {
                                //var bb=io.Contour.FindBoundingBox();
                                var offset       = tile.SourceArea.Location;
                                var sourcePoints = new List <Point>();
                                foreach (var contourPoint in io.Contour.GetPoints())
                                {
                                    double x           = Math.Round(contourPoint.X / scale + offset.X);
                                    double y           = Math.Round(contourPoint.Y / scale + offset.Y);
                                    var    sourcePoint = new Point((int)x, (int)y);
                                    sourcePoints.Add(sourcePoint);
                                }
                                var annotation = slideCache.Slide.CreateAnnotation(AnnotationType.PolygonLine);
                                foreach (var point in sourcePoints)
                                {
                                    annotation.AppendPoints(point);
                                }
                                annotation.Color = Color.OrangeRed;
                                annotation.Name  = null == io.Class?"bud":io.Class.Name;
                            }
                        }
                        Console.WriteLine(slideCache.SlideName + "-" + tile.Index + " done");
                        if (Console.KeyAvailable)
                        {
                            break;
                        }
                    }
                    slidePartitioner.Save(slidePartitionerFileName);
                    using (var heatMap = slidePartitioner.GenerateHeatMap(b => {
                        if (!b.HasValue)
                        {
                            return(Color.LightSeaGreen);
                        }
                        var c = (int)Math.Round(budCountRange.Normalize(b.Value) * 255d);
                        return(Color.FromArgb(c, c, c));
                    }))
                        slideCache.SetImage("budHeatMap", heatMap);
                }
            }
        }
Ejemplo n.º 7
0
        private static void Main(string[] args)
        {
            foreach (var slideName in Util.GetSlideFilenames(args))
            {
                using (var slideCache = new SlideCache(slideName)){
                    // var scale = 0.1f;
                    var scale    = 0.5f; // besser so laut 19.07.2018
                    var tileSize = 100;
                    var slidePartitionerFileName = slideCache.DataPath + "BudDetection.Buds.xml";
                    var slidePartitioner         = File.Exists(slidePartitionerFileName)?SlidePartitioner <int?> .Load(slidePartitionerFileName):new SlidePartitioner <int?>(slideCache.Slide, scale, new Size(tileSize, tileSize));

                    var heatMapHelper = new HeatMapHelper(slideCache.GetImage("tissueHeatMap"));
                    var budCountRange = new Range <int>();
                    var counter       = 0;

                    foreach (var tile in slidePartitioner.Values)
                    {
                        // test, ob schon was für die kackel berechnet wurde
                        if (tile.Data.HasValue)
                        {
                            Console.WriteLine(slideCache.SlideName + "-" + tile.Index + ":" + tile.Data.Value + " skipped");
                            budCountRange.Add(tile.Data.Value);
                            continue;
                        }

                        // soll kachel bearbeitet werden
                        var colors = heatMapHelper.GetAffectedColors(slideCache.Slide.Size, tile.SourceArea);
                        var values = heatMapHelper.GetAffectedValues(slideCache.Slide.Size, tile.SourceArea);
                        if (values.All(v => 255 == v))                      // 255 weiß
                        {
                            Console.WriteLine(slideCache.SlideName + "-" + tile.Index + ": no tissue");
                            continue;
                        }

                        using (var tileImage = slideCache.Slide.GetImagePart(tile)){
                            counter = counter + 1;

                            if (false)
                            {
                                var tileCache = slideCache.GetTileCache(tile.Index);
                                tileCache.SetImage("rgb", tileImage);                               //speichert unter C:\ProgramData\processingRepository\[slideCache.SlideName]\[Index]\... ansonsten tileImage.Save("[uri].png")
                            }

                            var r     = BudDetection.Detector.Execute(tileImage);                         // importent call
                            var layer = r.Value;

                            tile.Data = layer.Objects.Count;
                            budCountRange.Add(layer.Objects.Count);

                            // für alle gefundene objekte wird eine annotation angelegt
                            foreach (var io in layer.Objects)
                            {
                                //var bb=io.Contour.FindBoundingBox();
                                var offset       = tile.SourceArea.Location;
                                var sourcePoints = new List <Point>();
                                foreach (var contourPoint in io.Contour.GetPoints())
                                {
                                    double x           = Math.Round(contourPoint.X / scale + offset.X);
                                    double y           = Math.Round(contourPoint.Y / scale + offset.Y);
                                    var    sourcePoint = new Point((int)x, (int)y);
                                    sourcePoints.Add(sourcePoint);
                                }
                                var annotation = slideCache.Slide.CreateAnnotation(AnnotationType.PolygonLine);
                                foreach (var point in sourcePoints)
                                {
                                    annotation.AppendPoints(point);
                                }
                                annotation.Color = Color.PaleVioletRed;
                                annotation.Name  = null == io.Class?"bud":io.Class.Name;
                            }
                        }
                        if (counter % 100 == 0)
                        {
                            Console.WriteLine(slideCache.SlideName + "-" + tile.Index + " done");
                        }

                        if (Console.KeyAvailable)
                        {
                            break;
                        }
                    }

                    slidePartitioner.Save(slidePartitionerFileName);

                    // normalisierung
                    using (var heatMap = slidePartitioner.GenerateHeatMap(b => {
                        if (!b.HasValue)
                        {
                            return(Color.LightSeaGreen);
                        }
                        var c = (int)Math.Round(budCountRange.Normalize(b.Value) * 255d);
                        return(Color.FromArgb(c, c, c));                      // grauwert(hell == viele butts)
                    }))

                        slideCache.SetImage("budHeatMap", heatMap);
                }
            }
        }