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