protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.CreateTabContainer("Deconvolution"); this.TabContainer.Enabled = true; this.deconvolutedImageBox = new ImageListBox(() => this.DisplayedImage, this.SetDisplayedImage) { Parent = this.TabContainer, Height = 100 }; (new Button { Parent = this.TabContainer, Text = "deconvolute", Dock = DockStyle.Top }).Click += delegate { this.deconvolutedImageBox.Init(); foreach (var tuple in this.process()) { var map = new Map(tuple.Item1.Width, tuple.Item1.Height); if (tuple.Item2 != "Blue") { using (var gsp = new GrayscaleProcessor(tuple.Item1, RgbToGrayscaleConversion.JustReds)) { gsp.WriteBack = false; foreach (var grayscalePixel in gsp.Pixels()) { map[grayscalePixel.X, grayscalePixel.Y] = grayscalePixel.V > tuple.Item3 ? 1u : 0u; } } } else { using (var gsp = new GrayscaleProcessor(tuple.Item1, RgbToGrayscaleConversion.JustReds)) { gsp.WriteBack = false; foreach (var grayscalePixel in gsp.Pixels()) { map[grayscalePixel.X, grayscalePixel.Y] = 1u; } } } var layer = new ConnectedComponentCollector().Execute(map); layer.Name = tuple.Item2; this.addLayer(layer, true); this.deconvolutedImageBox.Add(tuple.Item1, tuple.Item2); } }; new Button { Text = "goto zoom", Parent = this.TabContainer, Dock = DockStyle.Top }.Click += delegate { WsiInterop.Navigation.Goto((float)this.zoomNumericUpDown.Value); }; this.zoomNumericUpDown = new NumericUpDown() { Parent = this.TabContainer, Dock = DockStyle.Top, Minimum = 0, Maximum = 1, Value = 0.5M, DecimalPlaces = 1, Increment = 0.1M }; }
private ObjectLayer RefillContours(ObjectLayer layer) { Map map = new Map(layer.Map.Width, layer.Map.Height); for (int i = 0; i < layer.Objects.Count; i++) { ImageObject obj = layer.Objects[i]; obj.Contour.Fill(map, obj.Id, true); } layer = new ConnectedComponentCollector().Execute(map); return(layer); }
private static ObjectLayer createLayer(Bitmap bitmap, int threshold, string name) { var map = new Map(bitmap.Width, bitmap.Height); using (var gsp = new SharpAccessory.Imaging.Filters.ColorDeconvolution().Get2ndStain(bitmap, SharpAccessory.Imaging.Filters.ColorDeconvolution.KnownStain.HaematoxylinDAB)){ gsp.WriteBack = false; foreach (var grayscalePixel in gsp.Pixels()) { map[grayscalePixel.X, grayscalePixel.Y] = grayscalePixel.V > threshold?1u:0u; } } var layer = new ConnectedComponentCollector().Execute(map); layer.Name = name; return(layer); }
private static ObjectLayer createLayer(Bitmap bitmap, int threshold, string name) { var map = new Map(bitmap.Width, bitmap.Height); using (var gsp = new GrayscaleProcessor(bitmap, RgbToGrayscaleConversion.JustReds)){ gsp.WriteBack = false; foreach (var grayscalePixel in gsp.Pixels()) { map[grayscalePixel.X, grayscalePixel.Y] = grayscalePixel.V > threshold?1u:0u; } } var layer = new ConnectedComponentCollector().Execute(map); layer.Name = name; return(layer); }
public ObjectLayer Execute(Bitmap image) { var m = new Map(image.Width, image.Height); using (var gp = new GrayscaleProcessor(image.Clone() as Bitmap, RgbToGrayscaleConversion.Mean)) for (var x = 0; x < image.Width; x++) { for (var y = 0; y < image.Height; y++) { m[x, y] = gp.GetPixel(x, y) < 200?0u:1u; } } var layer = new ConnectedComponentCollector().Execute(m); layer.Name = "lumina"; return(layer); }
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); }; }
private ObjectLayer RefillContours(ObjectLayer layer) { Map map = new Map(layer.Map.Width, layer.Map.Height); for (int i = 0; i < layer.Objects.Count; i++) { ImageObject obj = layer.Objects[i]; obj.Contour.Fill(map, obj.Id, true); } layer = new ConnectedComponentCollector().Execute(map); return layer; }
private ObjectLayer Execute3rdLevelSegmentation(ObjectLayer l2ndLevel, GrayscaleProcessor gpSobel, GrayscaleProcessor gpH, float targetArea) { List<Contour> finalContours = new List<Contour>(); for (int i = 0; i < l2ndLevel.Objects.Count; i++) { finalContours.Add(l2ndLevel.Objects[i].Contour); } double[] hBackground = this.GetBackgroundHistogram(l2ndLevel, gpH); double[] hForeground = this.GetForegroundHistogram(l2ndLevel, gpH); Parallel.For(0, l2ndLevel.Objects.Count, i => { ImageObject obj = l2ndLevel.Objects[i]; ContourProperties cp = ContourProperties.FromContour(obj.Contour); obj.Features.Add(new Feature("Area", cp.Area)); }); Map map = new Map(gpSobel.Width, gpSobel.Height); Parallel.For(0, gpH.Height, dy => { for (int dx = 0; dx < gpH.Width; dx++) { UInt32 h = gpH[dx, dy]; if (hForeground[h] <= hBackground[h]) continue; UInt32 id = l2ndLevel.Map[dx, dy]; if (id != 0) { ImageObject obj = l2ndLevel.Objects.GetObjectById(id); double area = obj.Features["Area"].Value; if (area > 0.33 * targetArea) continue; } map[dx, dy] = 0xffffffff; } }); ObjectLayer layer = new ConnectedComponentCollector().Execute(map); layer = new ContourOptimizer().RemoveNonCompactPixels(layer, 3); for (int i = 0; i < layer.Objects.Count; i++) { finalContours.Add(layer.Objects[i].Contour); } Contour[] contours = this.Sort(finalContours.ToArray(), gpSobel, gpH, targetArea); layer = this.CreateLayer(gpSobel.Width, gpSobel.Height, contours); Map finalMap = new Map(layer.Map, false); for (int dy = 0; dy < gpH.Height; dy++) for (int dx = 0; dx < gpH.Width; dx++) { if (l2ndLevel.Map[dx, dy] != 0) continue; if (map[dx, dy] != 0) continue; finalMap[dx, dy] = 0; } layer = new ConnectedComponentCollector().Execute(finalMap); layer = new ContourOptimizer().RemoveNonCompactPixels(layer, 3); layer = new ConcaveObjectSeparation().Execute(layer, 0.33, true); double minArea = Math.Max(0.1 * targetArea, MIN_AREA); layer = layer.CreateAbove(obj => { float area = ContourProperties.FromContour(obj.Contour).Area; return area > minArea; }); layer = this.RefillContours(layer); return layer; }
private ObjectLayer Execute3rdLevelSegmentation(ObjectLayer l2ndLevel, GrayscaleProcessor gpSobel, GrayscaleProcessor gpH, float targetArea) { List <Contour> finalContours = new List <Contour>(); for (int i = 0; i < l2ndLevel.Objects.Count; i++) { finalContours.Add(l2ndLevel.Objects[i].Contour); } double[] hBackground = this.GetBackgroundHistogram(l2ndLevel, gpH); double[] hForeground = this.GetForegroundHistogram(l2ndLevel, gpH); Parallel.For(0, l2ndLevel.Objects.Count, i => { ImageObject obj = l2ndLevel.Objects[i]; ContourProperties cp = ContourProperties.FromContour(obj.Contour); obj.Features.Add(new Feature("Area", cp.Area)); }); Map map = new Map(gpSobel.Width, gpSobel.Height); Parallel.For(0, gpH.Height, dy => { for (int dx = 0; dx < gpH.Width; dx++) { UInt32 h = gpH[dx, dy]; if (hForeground[h] <= hBackground[h]) { continue; } UInt32 id = l2ndLevel.Map[dx, dy]; if (id != 0) { ImageObject obj = l2ndLevel.Objects.GetObjectById(id); double area = obj.Features["Area"].Value; if (area > 0.33 * targetArea) { continue; } } map[dx, dy] = 0xffffffff; } }); ObjectLayer layer = new ConnectedComponentCollector().Execute(map); layer = new ContourOptimizer().RemoveNonCompactPixels(layer, 3); for (int i = 0; i < layer.Objects.Count; i++) { finalContours.Add(layer.Objects[i].Contour); } Contour[] contours = this.Sort(finalContours.ToArray(), gpSobel, gpH, targetArea); layer = this.CreateLayer(gpSobel.Width, gpSobel.Height, contours); Map finalMap = new Map(layer.Map, false); for (int dy = 0; dy < gpH.Height; dy++) { for (int dx = 0; dx < gpH.Width; dx++) { if (l2ndLevel.Map[dx, dy] != 0) { continue; } if (map[dx, dy] != 0) { continue; } finalMap[dx, dy] = 0; } } layer = new ConnectedComponentCollector().Execute(finalMap); layer = new ContourOptimizer().RemoveNonCompactPixels(layer, 3); //layer=new ConcaveObjectSeparation().Execute(layer, 0.33, true); double minArea = Math.Max(0.1 * targetArea, MIN_AREA); layer = layer.CreateAbove(obj => { float area = ContourProperties.FromContour(obj.Contour).Area; return(area > minArea); }); layer = this.RefillContours(layer); return(layer); }