Beispiel #1
0
        /// <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;
        }