/// <summary> /// Calculates the perimeter of every object in a labeled image. /// </summary> /// <param name="image">A labeled image to process</param> /// <returns>A Dictionary with perimeter per color label</returns> public static Dictionary<Color, int> Perimeters(this Color[,] image) { return image.ChainCode().ToDictionary(x => x.Key, x => x.Value.Count()); }
public static Dictionary<Color, Rectangle> BoundingBox(this Color[,] image) { Dictionary<Color, Tuple<int, int>> firstPixels = image.FirstPixels(); Dictionary<Color, int[]> chainCode = image.ChainCode(); Dictionary<Color, List<Tuple<int,int>>> borders = new Dictionary<Color, List<Tuple<int, int>>>(); Dictionary<Color, double> thetas = image.AxisOfLeastMomentInertia(); Dictionary<Color, Tuple<double, double>> centroids = image.Centroids(); Dictionary<Color, Rectangle> result = new Dictionary<Color, Rectangle>(); foreach (Color key in chainCode.Keys) { int[] value = chainCode[key]; Tuple<int, int> currentPixel = firstPixels[key]; List<Tuple<int, int>> listPixels = new List<Tuple<int, int>>(); listPixels.Add(currentPixel); borders.Add(key, listPixels); for (int i = 0; i < value.Length; i++) { currentPixel = translate(currentPixel.Item1, currentPixel.Item2, value[i]); borders[key].Add(currentPixel); //borders.Add(key, listPixels); } foreach (Tuple<int,int> c in borders[key]) image[c.Item1, c.Item2] = Color.White; double theta = thetas[key]; double centroidX = centroids[key].Item1; double centroidY = centroids[key].Item2; double sinTheta = Math.Sin(theta); double cosTheta = Math.Cos(theta); // Find min max for key int minX= 512, minY= 512, maxX = 0, maxY = 0; foreach ( Tuple<int,int> coord in borders[key] ) { double x = coord.Item1 - centroidX; double y = coord.Item2 - centroidY; int newX = (int)((cosTheta * x) + ( sinTheta * y )); int newY = (int)((-1 * sinTheta * x) + (cosTheta * y)); if ( newX < minX ) minX = newX; if (newX > maxX) maxX = newX; if (newY < minY) minY = newY; if (newY > maxY) maxY = newY; } if (new int[4] { minX, minY, maxX, maxY }.Any(x => x == int.MinValue || x == int.MaxValue)) continue; Rectangle boundingBox = new Rectangle(minX + (int)centroidX, minY + (int)centroidY, Math.Abs(minX) + maxX, Math.Abs(minY) + maxY); result.Add(key, boundingBox); } return result; }