public Node(Pixel pixel)
        {
            (this.pixels = new List<Pixel>()).Add(pixel);

            this.parent = null;
            this.children = new List<Node>();

            this.Highest = pixel.color;
            this.Variation = Double.MaxValue;
        }
 public void AddChild(Node child)
 {
     child.parent = this;
     children.Add(child);
 }
        private void ToRectangle(Node current, ref Int32 minX, ref Int32 minY, ref Int32 maxX, ref Int32 maxY)
        {
            foreach (var pixel in current.Pixels)
            {
                if (pixel.Position.X < minX) minX = pixel.Position.X;
                if (pixel.Position.Y < minY) minY = pixel.Position.Y;
                if (pixel.Position.X > maxX) maxX = pixel.Position.X;
                if (pixel.Position.Y > maxY) maxY = pixel.Position.Y;
            }

            foreach (var child in current.Children)
                ToRectangle(child, ref minX, ref minY, ref maxX, ref maxY);
        }
        private void MSERDetector(Node current)
        {
            if ((Double)current.Area < Parameters.MinArea * (Double)Length)
            {
                return;
            }

            if ((Double)current.Area < Parameters.MaxArea * (Double)Length && current.LocalMinimum())
            {
                stable.Add(current);
                return;
            }

            foreach (var child in current.Children)
            {
                MSERDetector(child);
            }
        }
        void DisjointSetForest()
        {
            /* 2. foreach p из V do {MakeSettree(p); MakeSetnode(p);
             * nodes[p]:= MakeNode(F(p)); lowestNode[p] := p;}; */

            for (Int32 p = 0; p < Length; p++)
            {
                QTree.MakeSet(p);
                QNode.MakeSet(p);

                /* MakeNode() */
                nodes[p] = new Node(pixels[p]);

                lowestNode[p] = p;
            }

            /* 3. foreach p из V in decreasing order of level for F
             * (F - интенсивность) do */
            for (Int32 p = 0; p < Length; p++)
            {
                accessible[pixels[p].Position.X, pixels[p].Position.Y] = p;

                Int32 curTree = QTree.Find(p);
                Int32 curNode = QNode.Find(lowestNode[curTree]);

                /* 6. foreach already processed neighbor
                    * (для уже обработанных, доступных) q of p with F(q) >= F(p)  */

                List<Int32> border = AccessibleBorderPixels(pixels[p].Position);

                for (Int32 q = 0; q < border.Count; q++)
                {
                    Int32 adjTree = QTree.Find(border[q]);
                    Int32 adjNode = QNode.Find(lowestNode[adjTree]);

                    if (curNode != adjNode)
                    {
                        if (nodes[curNode].Level == nodes[adjNode].Level)
                        {
                            curNode = MergeNodes(adjNode, curNode);
                        }
                        else
                        {
                            nodes[curNode].AddChild(nodes[adjNode]);
                            nodes[curNode].Highest = Math.Max(nodes[curNode].Highest, nodes[adjNode].Highest);
                        }

                        curTree = QTree.Link(adjTree, curTree);
                        lowestNode[curTree] = curNode;
                    }
                }
            }

            // 15. Root := lowestNode[Findtree(Findnode(0))] ;

            root = lowestNode[QTree.Find(QNode.Find(0))];
        }
        private void CalculateVariation(Node current)
        {
            current.CalculateVariation();

            foreach (var child in current.Children)
            {
                CalculateVariation(child);
            }
        }