我正在对图像进行连接组件操作:所有连接且具有相同值的像素将被分配相同的标签。
一个例子是,如果输入是:
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]);
}
}