/// <summary> /// Gets the average colors of this points /// </summary> /// <param name="bmp"></param> /// <param name="Points"></param> /// <returns></returns> public static Color AverageColor(this LockBitmap bitmap, IEnumerable <Point> Points) { //Used for tally int r = 0; int g = 0; int b = 0; int total = 0; foreach (var p in Points) { Color clr = bitmap[p.X, p.Y]; r += clr.R; g += clr.G; b += clr.B; total++; } //Calculate average r /= total; g /= total; b /= total; return(Color.FromArgb(r, g, b)); }
/// <summary> /// Mark the path /// </summary> /// <param name="bitmap"></param> /// <returns></returns> public static void ChangeColor(this LockBitmap bitmap, IEnumerable <Point> Path, Color Color) { foreach (var item in Path) { bitmap.SetPixel(item.X, item.Y, Color); } }
public static KeyValuePair <Bitmap, int> HasLogo(Bitmap source, int minShapes, int MinPixels = 30, int MaxPixels = 150) { var sourceData = new LockBitmap(source); var target = new Bitmap(source.Width, source.Height, PixelFormat.Format24bppRgb); var targetData = new LockBitmap(target); sourceData.LockBits(); targetData.LockBits(); try { //Filter the shapes similar to logo var closedPaths = sourceData.FindClosedAreas(MinPixels, MaxPixels); var shapesFopund = closedPaths.Count; if (closedPaths.Count >= minShapes) { closedPaths = closedPaths.FindShapesInCirclesBorder(minShapes); foreach (var item in closedPaths) { // var cmykColors= item.ConvertAll(c => ColorSpaceHelper.RGBtoCMYK(sourceData[c.X, c.Y])); targetData.ChangeColor(item, Color.Red); } } var conf = closedPaths.Count < minShapes ? 0 : 100 - Math.Abs(closedPaths.Count - 5) * 20; return(new KeyValuePair <Bitmap, int>(target, conf)); } finally { sourceData.UnlockBits(); targetData.UnlockBits(); //bitmap.Save("c:\\d\\logo.png"); } }
/// <summary> /// Finds all areas with this color /// </summary> public static List <Point> GetConnectedPixels(this LockBitmap bitmap, int X, int Y, Predicate <Point> NavigateToThisPoint) { var path = new Dictionary <Point, int>(); Queue q = new Queue(); path[new Point(X, Y)] = 0; q.Enqueue(new Point(X, Y)); var pixelColor = bitmap[X, Y]; while (q.Count > 0) { var p = (Point)q.Dequeue(); X = p.X; Y = p.Y; for (int i = 1; i <= 4; i++) { int x2 = X; int y2 = Y; switch (i) { case 1: //left x2--; break; case 2: //Right x2++; break; case 3: //down y2++; break; case 4: //up y2--; break; } if (x2 < bitmap.Width && x2 >= 0 && y2 < bitmap.Height && y2 >= 0) { var p2 = new Point(x2, y2); if (!path.ContainsKey(p2) && bitmap[x2, y2].IsSimilarTo(pixelColor) && (NavigateToThisPoint == null || NavigateToThisPoint(p2))) { q.Enqueue(p2); path[p2] = 0; } } } } return(path.Keys.ToList()); }
/// <summary> /// Finds all closed paths with the same color /// </summary> /// <param name="bitmap"></param> /// <returns></returns> public static List <List <Point> > FindClosedAreas(this LockBitmap bitmap, int MinPixelsCount, int MaxPixelsCount) { var paths = new List <List <Point> >(); var added = new Dictionary <Point, int>(); var pixels = bitmap.Points.ToList(); while (pixels.Count > 0) { var path = GetConnectedPixels(bitmap, pixels[0].X, pixels[0].Y, p => !added.ContainsKey(p)); foreach (var item in path) { added[item] = 0; } paths.Add(path); pixels = pixels.Except(path).ToList(); } paths.RemoveAll(c => c.Count <MinPixelsCount || c.Count> MaxPixelsCount); // paths.Sort((c1, c2) => c2.Count.CompareTo(c1.Count)); return(paths); }