public static double DistanceTo(this Recognizer.Centroid first, ImageInfo info) { double distance = 0.0; for (int i = 0; i < ImageInfo.PropertiesCount; ++i) { distance += Math.Pow(first.PropertyValues[i] - info.GetPropertyByIndex(i), 2); } distance = Math.Sqrt(distance); return distance; }
public static List<ImageInfo> CalculateStats(int[,] pic, Dictionary<int, List<Point>> pointsByLabel) { Func<double, double> sqrt = Math.Sqrt; Func<double, double> square = x => Math.Pow(x, 2); int height = pic.GetLength(0); int width = pic.GetLength(1); var images = new List<ImageInfo>(); foreach (KeyValuePair<int, List<Point>> imagePoints in pointsByLabel) { var info = new ImageInfo(); info.Label = imagePoints.Key; List<Point> points = imagePoints.Value; foreach (Point p in points) { info.Area += 1; if (p.X - 1 < 0 || p.X + 1 >= width || p.Y - 1 < 0 || p.Y + 1 >= height) { // border info.Perimeter += 1; } else if (pic[p.Y, p.X + 1] == -1 || pic[p.Y, p.X - 1] == -1 || pic[p.Y + 1, p.X] == -1 || pic[p.Y - 1, p.X] == -1) { info.Perimeter += 1; } } Debug.WriteLine("Area: {0}", info.Area); Debug.WriteLine("Perimeter: {0}", info.Perimeter); info.Compactness = square(info.Perimeter) / info.Area; Debug.WriteLine("Compactness: {0}", info.Compactness); info.XAverage = points.Sum(p => p.X) / info.Area; info.YAverage = points.Sum(p => p.Y) / info.Area; Debug.WriteLine("XAverage: {0}", info.XAverage); Debug.WriteLine("YAverage: {0}", info.YAverage); info.M20 = 0; info.M11 = 0; info.M02 = 0; foreach (Point p in points) { info.M20 += (p.X - info.XAverage) * (p.X - info.XAverage); info.M11 += (p.X - info.XAverage) * (p.Y - info.YAverage); info.M02 += (p.Y - info.YAverage) * (p.Y - info.YAverage); } info.Elongation = (info.M20 + info.M02 + sqrt(square(info.M20 - info.M02) + 4 * info.M11 * info.M11)) / (info.M20 + info.M02 - sqrt(square(info.M20 - info.M02) + 4 * info.M11 * info.M11)); Debug.WriteLine("Elongation: {0}", info.Elongation); Debug.WriteLine("M11: " + info.M11); Debug.WriteLine("M20: " + info.M20); Debug.WriteLine("M02: " + info.M02); info.Orientation = 0.5 * Math.Atan2(2 * info.M11, info.M20 - info.M02); Debug.WriteLine("Orientation: " + info.Orientation); images.Add(info); } foreach (ImageInfo image in images) { if (double.IsInfinity(image.Elongation)) { Debugger.Break(); image.Elongation = images .Where(im => !double.IsInfinity(im.Elongation)) .Max(im => im.Elongation); } else if (double.IsNaN(image.Elongation)) { Debugger.Break(); } } return images; }
private static int FindIndexOfNearestClusterMean(ImageInfo image, Centroid[] means) { Debug.WriteLine("Image's nearest mean:"); int nearestMeanIndex = -1; double minDistance = double.MaxValue; for (int i = 0; i < means.Length; ++i) { double distanceToMean = means[i].DistanceTo(image); Debug.WriteLine("Distance to {0} = {1}", i, distanceToMean); if (distanceToMean < minDistance) { nearestMeanIndex = i; minDistance = distanceToMean; } } if (nearestMeanIndex == -1) Debugger.Break(); Debug.WriteLine("Nearest mean index: {0}", nearestMeanIndex); return nearestMeanIndex; }