C# 洪水中的堆栈溢出错误

C# 洪水中的堆栈溢出错误,c#,image,bitmap,stack-overflow,flood-fill,C#,Image,Bitmap,Stack Overflow,Flood Fill,我试图在连接的二进制图像区域上实现泛洪填充,但是我得到了StackOverflow错误。此外,如何使用不同的颜色为每个区域着色 谢谢 public void FloodFill(int x, int y) { Bitmap bitmap = (Bitmap)pictureBox1.Image; if ((x < 0) || (y < 0) || (x >= bitmap.Width) || (y >= bitmap.Height)) { return;

我试图在连接的二进制图像区域上实现泛洪填充,但是我得到了StackOverflow错误。此外,如何使用不同的颜色为每个区域着色

谢谢

public  void FloodFill(int x, int y)
{
    Bitmap bitmap = (Bitmap)pictureBox1.Image;

    if ((x < 0) || (y < 0) || (x >= bitmap.Width) || (y >= bitmap.Height)) { return; }

    Color cl = bitmap.GetPixel(x, y); // error An unhandled exception of type 'System.StackOverflowException' occurred in System.Drawing.dll

    if ((cl.R != 255) || (cl.G != 255) || (cl.B != 255)) { return; }
    if ((cl.R == 255) && (cl.G == 255) && (cl.B == 255)) {
        bitmap.SetPixel(x, y, Color.FromArgb(255, 255, 0, 0));
    }
    FloodFill(x, y - 1);
    FloodFill(x + 1, y - 1);
    FloodFill(x + 1, y);
    FloodFill(x + 1, y + 1);
    FloodFill(x, y + 1);
    FloodFill(x - 1, y + 1);
    FloodFill(x - 1, y);
    FloodFill(x - 1, y - 1);
}
for (int i = 0; i < pictureBox1.Width; i++)
{
    for (int j = 0; j < pictureBox1.Height; j++) {
        Point p = new Point(i, j);
        FloodFill(p.X, p.Y);
    }
}

我想问题与递归的顺序有关。在最坏的情况下,您几乎要先处理整个图像深度。递归的深度可能与图像中的总像素数一样深

假设我们从10x10图像的左下角开始。前几个步骤是:

我们递归地输入第一个FloodFillx,y-1,直到y=0=>堆栈深度10 回溯一步,下一步我们可以做的是泛光填充x+1,y直到x=9,y=0=>堆栈深度19 再次回溯,下一步我们做的是泛光填充x-1,y直到x=1,y=0=>堆栈深度27 现在是我们第一次需要在堆栈中上升一个以上的级别。 因此,您需要一个至少为图像2*宽度+2*高度的堆栈大小——以上只是一个快速分析。这可能太过分了


建议:使用迭代算法

PMF是正确的;您应该为此使用迭代算法

迭代算法为:

Fill(coordinate)
    stack = new Stack<Coordinate>()
    stack.Push(coordinate)
    while !stack.IsEmpty
        current = stack.Pop();
        if bitmap[current] is not white then continue
        bitmap[current] = black
        stack.Push(current.NorthNeighbour)            
        stack.Push(current.SouthNeighbour)
        etc.

你知道这是怎么回事吗?其思想是,您实际上分配自己的堆栈,而不是将调用堆栈用作临时存储

你还建议使用什么算法?我在哪里可以找到它的代码?谢谢,我正在使用8-连接邻居方法,我将使用4-连接邻居。我遵循这篇文章的伪代码:@Adriano,无限递归问题实际上不会发生。FloodFill0,0将像素0,0设置为青色,然后调用FloodFill0,1,后者将调用FloodFill0,0,后者将返回,因为像素0,0是青色,而不是白色。该算法是无效的,但不应该无限期地递归。该代码在较小的图像区域运行良好,但在较大的图像上会出错,仍然不是solved@g.rocket你说得对!汉娜:那么你的堆栈空间就用完了。谢谢你的回答,我怎样才能增加堆栈的大小呢?我是新的c用户。@HannahSolomons:你永远不会增加堆栈大小。您编写的算法使用更少的堆栈。@HannahSolomons:有一个丑陋的黑客在增加C应用程序主线程的堆栈大小。但这真的是最后一件事。@PFM:谢谢你的信息谢谢你的回答,我将根据新算法重新编写代码。