Понравился алгоритм для решения этой задачи, активно используется стек так что он эффективен на не больших данных, либо на не больших связных поверхностях. Типичным способом решения этой задачи это поиск в глубину. Ниже исходник для выделения однотонных объектов на изображении.
class Program { static void Main(string[] args) { if (args.Length < 0) { Console.WriteLine("[*] Input image path"); return; } GLOBAL_DATA.Image2Recog = (Bitmap)Bitmap.FromFile(args[0]); GLOBAL_DATA.Width = GLOBAL_DATA.Image2Recog.Width-1; GLOBAL_DATA.Height = GLOBAL_DATA.Image2Recog.Height-1; SamePixelRecognition obj = new SamePixelRecognition(); obj.FindSameLinkedPixels(); Console.WriteLine("There is a {0} linked surface in image",GLOBAL_DATA.Count); Console.ReadKey(); } } class GLOBAL_DATA { public static Bitmap Image2Recog; public static int Count=0; public static int Width = 0; public static int Height = 0; public static Color White = Color.FromArgb(255, 255, 255, 255); } class SamePixelRecognition { public void FindSameLinkedPixels() { for(int y = 0;y < GLOBAL_DATA.Height; y++) for (int x = 0; x < GLOBAL_DATA.Width; x++) { if (GLOBAL_DATA.Image2Recog.GetPixel(x, y) != GLOBAL_DATA.White) { Color tmp = GLOBAL_DATA.Image2Recog.GetPixel(x, y); RemovePixel(x, y); GLOBAL_DATA.Count++; } } } private void RemovePixel(int x, int y) { int[] wayX = {-1,0,1,0 }; int[] wayY = {0,-1,0,1 }; int tX; int tY; GLOBAL_DATA.Image2Recog.SetPixel(x, y, GLOBAL_DATA.White); for (int i = 0; i < wayX.Length; i++) { tX = wayX[i] + x; tY = wayY[i] + y; if (tX < 0 || tX > GLOBAL_DATA.Width || tY < 0 || tY > GLOBAL_DATA.Height) continue; if (GLOBAL_DATA.Image2Recog.GetPixel(tX, tY) != GLOBAL_DATA.White) this.RemovePixel(tX, tY); } } }
Используется как видите C#, алгоритм решает задачу, на поиск связанных пикселов т.е. тех, которые расположена рядом друг с другом.
Оставить комментарий