/// <summary> /// Region growing to encode the source image data. /// </summary> /// <param name="locationPool"></param> /// <param name="maximumDistance"></param> /// <param name="type"></param> /// <returns></returns> private static HashSet<Region> Process(LocationPool locationPool, double maximumDistance, RegionType type) { HashSet<Region> result = new HashSet<Region>(); List<Location> todoList = new List<Location>(); //let's process pixels into regions Region region = null; HashSet<Location> alreadyChecked = new HashSet<Location>(); while (!locationPool.Empty()) { alreadyChecked.Clear(); Location seed = locationPool.RandomLocation(); //Console.WriteLine("Have seed " + seed); if (type == RegionType.MonoRegion) { region = new MonoRegion(); } else if (type == RegionType.MultiColorRegion) { MultiColorRegion multiColorRegion = new MultiColorRegion(maximumDistance); region = multiColorRegion; } region.Add(seed); region.Origin = seed.Point; seed.Region = region; locationPool.SetMarked(seed); alreadyChecked.Add(seed); AddNeighbors(seed, todoList, alreadyChecked); todoList.Sort((x, y) => (int)(SxzColor.GetColorDistance(seed.Color, x.Color) - SxzColor.GetColorDistance(seed.Color, y.Color))); int sortCounter = 0; //inner loop while (todoList.Count != 0) { //Console.WriteLine("Unmarked total " + locationPool.Unmarked.Count + " and todolist total " + todoList.Count); seed = todoList[0]; todoList.RemoveAt(0); sortCounter++; if (seed.Marked) { throw new Exception("Location already marked!"); } if (!region.IsValid(seed)) { //we can process non-adjacent pixels by adding neighbors here and sorting before returning but limit the distance from an already //validated location continue; } //Console.WriteLine("Parsed pixel " + seed); //we have a winner! region.Add(seed); locationPool.SetMarked(seed); AddNeighbors(seed, todoList, alreadyChecked); //if (todoList.Count < 1000) if (todoList.Count < 1000 || sortCounter > 1000) { //let's limit the number to be sorted for performance sake todoList.Sort((x1, y1) => (int)(SxzColor.GetColorDistance(seed.Color, x1.Color) - SxzColor.GetColorDistance(seed.Color, y1.Color))); sortCounter = 0; } } result.Add(region); } return result; }