private static WatershedPixel[,] PixelMap(float[,] input) { var width = input.GetLength(0); var height = input.GetLength(1); var result = new WatershedPixel[width, height]; for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { result[x, y] = new WatershedPixel(x, y, input[x, y]); } } return(result); }
public static float[,] Watershed(float[,] input, byte color = 255) { var width = input.GetLength(0); var height = input.GetLength(1); var queue = new Queue <WatershedPixel>(); var result = new float[width, height];// input.Clone() as float[,]; var map = PixelMap(input); var histogram = PixelHistogram(map); var distance = 0; var end = new WatershedPixel(-1, -1, 0); var count = 0; var label = 0; for (var h = 0; h < histogram.Count; h++) { foreach (var pixel in histogram[h]) { pixel.Label = WatershedLabel.Mask; foreach (var neighbour in Neighbours(map, pixel.X, pixel.Y, width, height)) { if (neighbour == null) { continue; } if (neighbour.Label > 0 || neighbour.Label == WatershedLabel.Watershed) { pixel.Distance = 1; queue.Enqueue(pixel); break; } } } distance = 1; queue.Enqueue(end); while (true) { var pixel = queue.Dequeue(); if (pixel.Equals(end)) { if (queue.Count == 0) { break; } else { queue.Enqueue(pixel); distance++; pixel = queue.Dequeue(); } } foreach (var neighbour in Neighbours(map, pixel.X, pixel.Y, width, height)) { if (neighbour == null) { continue; } if (neighbour.Distance <= distance && (neighbour.Label > 0 || neighbour.Label == WatershedLabel.Watershed)) { if (neighbour.Label > 0) { if (pixel.Label == WatershedLabel.Mask) { pixel.Label = neighbour.Label; } else if (pixel.Label != neighbour.Label) { pixel.Label = WatershedLabel.Watershed; count++; } } else if (pixel.Label == WatershedLabel.Mask) { pixel.Label = WatershedLabel.Mask; count++; } } else if (neighbour.Label == WatershedLabel.Mask && neighbour.Distance == 0) { neighbour.Distance = distance + 1; queue.Enqueue(neighbour); } } } foreach (var pixel in histogram[h]) { pixel.Distance = 0; if (pixel.Label == WatershedLabel.Mask) { label++; pixel.Label = label; queue.Enqueue(pixel); while (queue.Count > 0) { var n = queue.Dequeue(); foreach (var neighbour in Neighbours(map, n.X, n.Y, width, height)) { if (neighbour == null) { continue; } if (neighbour.Label == WatershedLabel.Mask) { neighbour.Label = label; queue.Enqueue(neighbour); } } } } } } if (count > 0) { for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { if (map[x, y].Label == WatershedLabel.Watershed) { result[x, y] = color; } } } } return(result); }
public override bool Equals(object obj) { WatershedPixel p = (WatershedPixel)obj; return(X == p.X && X == p.Y); }