private static void AddConnectedPoints(CoordinateList existingPoints, Point firstPixel, ImageCache image, CoordinateList blacklistedPoints, int minX, int maxX, int minY, int maxY) { if (image[firstPixel.X, firstPixel.Y] <= 0 && firstPixel.X >= minX && firstPixel.X < maxX && firstPixel.Y >= minY && firstPixel.Y < maxY) { return; } var q = new Queue <Point>(); if (!existingPoints.Exists(firstPixel)) { existingPoints.Add(firstPixel); q.Enqueue(firstPixel); } while (q.Count > 0) { var n = q.Dequeue(); if (n.X + 1 <= maxX && image[n.X + 1, n.Y] > 0 && !existingPoints.Exists(n.X + 1, n.Y) && (blacklistedPoints == null || !blacklistedPoints.Exists(n.X + 1, n.Y))) { var np = new Point(n.X + 1, n.Y); existingPoints.Add(np); q.Enqueue(np); } if (n.X - 1 >= minX && image[n.X - 1, n.Y] > 0 && !existingPoints.Exists(n.X - 1, n.Y) && (blacklistedPoints == null || !blacklistedPoints.Exists(n.X - 1, n.Y))) { var np = new Point(n.X - 1, n.Y); existingPoints.Add(np); q.Enqueue(np); } if (n.Y - 1 >= minY && image[n.X, n.Y - 1] > 0 && !existingPoints.Exists(n.X, n.Y - 1) && (blacklistedPoints == null || !blacklistedPoints.Exists(n.X, n.Y - 1))) { var np = new Point(n.X, n.Y - 1); existingPoints.Add(np); q.Enqueue(np); } if (n.Y + 1 < maxY && image[n.X, n.Y + 1] > 0 && !existingPoints.Exists(n.X, n.Y + 1) && (blacklistedPoints == null || !blacklistedPoints.Exists(n.X, n.Y + 1))) { var np = new Point(n.X, n.Y + 1); existingPoints.Add(np); q.Enqueue(np); } } }
public void SaveClickMarkers(string inputImage, string outputPath, CoordinateList clickPoints) { using (Image <Rgba32> image = Image.Load(inputImage)) { foreach (var point in clickPoints) { for (int x = -4; x <= 4; x++) { for (int y = -4; y <= 4; y++) { image[point.X + x, point.Y + y] = Rgba32.Red; } } } image.Save(outputPath); } }
internal static List <Point> FindCharacterPixelPoints(Point firstPixel, ImageCache image, CoordinateList blacklistedPoints, int minX, int maxX, int minY, int maxY) { var characterPoints = new CoordinateList(); AddConnectedPoints(characterPoints, firstPixel, image, blacklistedPoints, minX, maxX, minY, maxY); var midX = (int)characterPoints.Average(p => p.X); //Scan down from the initial midpoint for gap characters //Account for gaps such as in i or j for (int y = characterPoints.Where(p => p.X == midX).Max(p => p.Y) + 1; y < maxY; y++) { AddConnectedPoints(characterPoints, new Point(midX, y), image, blacklistedPoints, minX, maxX, minY, maxY); } //Scan up from new midpoint for gap characters that have a bit sticking out the front. Account for gaps like in ; midX = (int)characterPoints.Average(p => p.X); var highestY = characterPoints.Min(p => p.X == midX ? p.Y : maxY); for (int i = highestY; i >= minY; i--) { AddConnectedPoints(characterPoints, new Point(midX, i), image, blacklistedPoints, minX, maxX, minY, maxY); } //Account for crazy gaps such as in % var foundNewPixels = false; do { foundNewPixels = false; var maxCharX = characterPoints.Max(p => p.X); for (int y = characterPoints.Where(p => p.X == maxCharX).Min(p => p.Y) + 1; y < minY + ((maxY - minY) * 0.75f); y++) { var origCount = characterPoints.Count; AddConnectedPoints(characterPoints, new Point(maxCharX, y), image, blacklistedPoints, minX, maxX, minY, maxY); if (characterPoints.Count > origCount) { foundNewPixels = true; } } } while (foundNewPixels); return(new List <Point>(characterPoints)); }
internal static TargetMask FindCharacterMask(Point firstPixel, ImageCache image, CoordinateList blacklistedPoints, int minX, int maxX, int minY, int maxY) { var points = FindCharacterPixelPoints(firstPixel, image, blacklistedPoints, minX, maxX, minY, maxY); var minPointX = points.Min(p => p.X); var mask = new bool[points.Max(p => p.X) - points.Min(p => p.X) + 1, maxY - minY]; var softMask = new float[points.Max(p => p.X) - points.Min(p => p.X) + 1, maxY - minY]; var pixelCount = 0; float softPixelCount = 0; foreach (var p in points) { mask[p.X - minPointX, p.Y - minY] = true; softMask[p.X - minPointX, p.Y - minY] = image[p.X, p.Y]; softPixelCount += image[p.X, p.Y]; pixelCount++; } return(new TargetMask(mask, points.Max(p => p.X), minPointX, points.Max(p => p.X) - minPointX + 1, pixelCount, softPixelCount, softMask)); }