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