Esempio n. 1
0
 private static void InitiateColorSegments(IList <Tree> segments, ColorsOfSegments colorsOfSegments, CancellationToken token)
 {
     if (colorsOfSegments == ColorsOfSegments.Random)
     {
         Random rand = new Random();
         foreach (var segment in segments)
         {
             Color color;
             do
             {
                 token.ThrowIfCancellationRequested();
                 color = Color.FromArgb(rand.Next(0, 256), rand.Next(0, 256), rand.Next(0, 256));
             }while (!IsUniqueColor(segments, color));
             segment.SetColor(color);
         }
     }
     else
     {
         foreach (var segment in segments)
         {
             segment.SetColor(segment.Root.Color);
         }
     }
 }
Esempio n. 2
0
        public static Bitmap RunSeparation(Bitmap sourceBitmap, SegmentationType type, Connectivity connectivity, double delta, IntensivityStandard standard, ColorsOfSegments colorsOfSegments, CancellationToken token)
        {
            Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);

            Pixel[,] graphFromSourceBitmap = BuildGraphByImage(sourceBitmap);

            // Получаем набор связных ребер для данного пикселя
            IList <Edge> collectionOfEdges = GetEdges(graphFromSourceBitmap, connectivity);

            // Присваиваем им вес в зависимости от выбранного способа сегментации и сортируем их по возрастанию
            collectionOfEdges = SortEdges(collectionOfEdges, type, standard);

            // Создадим коллекцию для будующих сегментов, первым сегментом будет первое ребро из нашего полученного graphFromSoueceBitmap.
            List <Tree> segments = new List <Tree>()
            {
                new Tree(collectionOfEdges.First())
            };

            // На начальном этапе имеется набор минимальных деревьев, состоящих из одного ребра, имеющего свой вес. Объекты отсортированы по возрастанию.
            // Делаем обход по всем пикселям, объединяя соседние в деревья (либо соседние деревья в одно), если они удовлетворяют критерию похожести
            foreach (var edge in collectionOfEdges)
            {
                token.ThrowIfCancellationRequested();
                if (edge.EndPixel.Root == null && edge.StartPixel.Root == null)
                {
                    //Оба пикселя ребра не принадлежат ни одному из сегментов, значит такого сегмента еще нет и его необходимо создать
                    segments.Add(new Tree(edge));
                }
                else if (edge.StartPixel.Root != null && edge.EndPixel.Root == null)
                {
                    Tree tree = GetTreeByRoot(edge.StartPixel.Root, segments);
                    // Первый пиксель ребра содержится в каком то сегменте, нужно проверить на возможноть присоединения ребра к treeOfStartPixel
                    if (Math.Abs(edge.Weight - tree.MaxWeightEdge.Weight) > delta)
                    {
                        // Перепад больше заданного параметра delta, поэтому мы не присоединяем это ребро к treeOfStartPixel,
                        // переходим к рассмотрению следующего ребра
                        continue;
                    }
                    else
                    {
                        // Перепад удовлетворяет заданному параметру delta, поэтому мы присоединяем это ребро к treeOfStartPixel
                        tree.AddEdge(edge.StartPixel, edge.EndPixel);
                    }
                }
                else if (edge.StartPixel.Root == null && edge.EndPixel.Root != null)
                {
                    Tree tree = GetTreeByRoot(edge.EndPixel.Root, segments);
                    // Второй пиксель ребра содержится в каком то сегменте, нужно проверить на возможноть присоединения ребра к treeOfEndPixel
                    if (Math.Abs(edge.Weight - tree.MaxWeightEdge.Weight) > delta)
                    {
                        // Перепад больше заданного параметра delta, поэтому мы не присоединяем это ребро к treeOfStartPixel,
                        // переходим к рассмотрению следующего ребра
                        continue;
                    }
                    else
                    {
                        // Перепад удовлетворяет заданному параметру delta, поэтому мы присоединяем это ребро к treeOfStartPixel
                        tree.AddEdge(edge.EndPixel, edge.StartPixel);
                    }
                }
                else if (edge.EndPixel.Root.Equals(edge.StartPixel.Root))
                {
                    // Точки этого ребра уже содержаться в одном дереве, поэтому переходим к следующему ребру
                    continue;
                }
                else
                {
                    Tree firstTree  = GetTreeByRoot(edge.StartPixel.Root, segments);
                    Tree secondTree = GetTreeByRoot(edge.EndPixel.Root, segments);
                    // Пиксели ребра содержатся в разных сегментах, нужно проверить возможность их объединения
                    if (Math.Abs(edge.Weight - firstTree.MaxWeightEdge.Weight) > delta ||
                        Math.Abs(edge.Weight - secondTree.MaxWeightEdge.Weight) > delta)
                    {
                        // Если перепад на границе и внутри хотя бы одного сегмента больше заданного параметра delta,
                        // тогда эти сегменты не объединяются и переходим к рассмотрению следующего ребра
                    }
                    else
                    {
                        // Перепад на границе удовлетворяет заданному параметру delta, нужно объединить эти сегменты
                        // Сначала добавим ребро к графу
                        firstTree.AddEdge(edge);
                        // Потом присоединим второе дерево
                        firstTree.Join(secondTree);
                        // Удалим сегмент после его присоединения
                        segments.Remove(secondTree);
                    }
                }
            }

            // Сгенерируем цвета для полученных областей
            InitiateColorSegments(segments, colorsOfSegments, token);

            // Заполним resultBitmap
            foreach (var tree in segments)
            {
                foreach (var pixel in tree.Pixels)
                {
                    resultBitmap.SetPixel(pixel.X, pixel.Y, tree.Color);
                }
            }

            return(resultBitmap);
        }