Exceed the maximum recursion depth

209 Views Asked by At

I am doing a connected component operation on images: all of the pixels which are connected and have the same value will be assigned the same label.

An example is that if the input is:

1 1 2 2

2 4 4 1

1 5 1 1

it should return:

1 1 2 2

3 4 4 5

6 7 5 5

Two blobs which have value 1 has been reassigned to 1 and 5.

This code works for small images. But when applying to larger one (512x512), it usually reach the maximum number of recursive stack allowed (Python, Visual Studio C++ but not gcc C++). How to fix the problem?

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;
}

Testing code is:

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

There are 0 best solutions below