超过最大递归深度

时间:2014-11-19 20:36:52

标签: python c++ algorithm recursion tail-recursion

我正在对图像进行连接组件操作:所有连接且具有相同值的像素将被分配相同的标签。

一个例子是,如果输入是:

  

1 1 2 2

     

2 4 4 1

     

1 5 1 1

它应该返回:

  

1 1 2 2

     

3 4 4 5

     

6 7 5 5

两个值为1的blob已重新分配为1和5.

此代码适用于小图片。但是当应用于较大的(512x512)时,它通常会达到允许的最大递归堆栈数(Python,Visual Studio C ++但不是gcc C ++)。如何解决问题?

vector<int> neighbors(int pixel, int height, int width)
// return neighboring pixels
{
    assert(pixel < height *width);
    vector<int> indexes;
    if (pixel % width == width - 1)
    {
        indexes.push_back(pixel - 1);
        indexes.push_back(pixel - width);
        indexes.push_back(pixel + width);
    }
    else if (pixel % width == 0)
    {
        indexes.push_back(pixel + 1);
        indexes.push_back(pixel - width);
        indexes.push_back(pixel + width);
    }
    else
    {
        indexes.push_back(pixel + 1);
        indexes.push_back(pixel - 1);
        indexes.push_back(pixel - width);
        indexes.push_back(pixel + width);
    }
    vector<int> out;
    for(int i = 0; i < indexes.size(); i++)
    {
        if (indexes[i] >= 0 && indexes[i] < height*width)
            out.push_back(indexes[i]);
    }
    return out;
}

void floodfill(const unsigned char *im, unsigned char *out, int pixel, int height, int width, int label)
// starting from the pixel, label all connected labels to pixel
{
    if (*(out + pixel) == 0)
    {
        *(out + pixel) = label;

        vector<int> ns = neighbors(pixel, height, width);
        for(int i = 0; i < ns.size(); i++)
        {
            if ((*(out + ns[i]) == 0) && *(im + ns[i]) == *(im + pixel))
            {
                floodfill(im, out, ns[i], height, width, label);
            }
        }
    }
}

int ConnectedComponent(const unsigned char *im, unsigned char *out, int height, int width)
{
    for (int i = 0; i < height*width; i++)
        *(out+i) = 0;

    int label = 0;
    for (int i = 0; i < height *width; i++)
    {
        if (*(out + i) == 0)
        {
            label++;
            floodfill(lev, out, i, height, width, label);
        }
    }
    return label;
}

测试代码是:

TEST(testLulu, connectedcomponenet)
{
    unsigned char lev[12] = {1,1,2,2,2,4,4,1,1,5,1,1};
    unsigned char * out = new unsigned char[12]();
    ConnectedComponent(lev, out, 3,4);
    unsigned char correct[12] = {1,1,2,2,3,4,4,5,6,7,5,5};

    for (int i = 0; i<12; i++)
    {
        EXPECT_EQ(correct[i], out[i]);
    }
}

0 个答案:

没有答案