我目前正在研究一种算法,有时我必须遍历图像并将具有相同属性的像素分组。我从最左上角的像素开始并使用递归:从输入像素我可以获得高度相邻像素,如果第一个具有相同的属性,那么我通过将此像素作为输入像素传递来调用相同的函数。
这是一些代码(请记住,这仍在进行中)。基本调用者:
// R.A.G.
for( std::vector<Cell*>::iterator iterCell = cellVec.begin();
iterCell != cellVec.end(); ++iterCell )
{
Cell* mother = (*iterCell);
if( mother->visited != true )
{
mother->visited = true;
}
CheckNeighbors( mother );
}
递归函数:
void
CheckNeighbors( Cell* mother )
{
Cell* cell = nullptr;
// Get the neighbours for the cell.
// 5 6 7
// 4 c 0
// 3 2 1
if( (cell=CheckCell( 1, 0, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( 1, 1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( 0, 1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( -1, 1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( -1, 0, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( -1, -1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( 0, -1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( 1, -1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
}
我如何检查细胞:
Cell*
CheckCell( int x, int y, Cell* cell )
{
// Here a cell is one pixel, but it depends on the size of the window we choose.
// So for an image of 640*480, windowSize = 1, w = 640, h = 480
x += cell->window.x()/windowSize;
y += cell->window.y()/windowSize;
// The cell at (x, y) coordinates is not in the map
if( x < 0 || x >= w || y < 0 || y >= h ) return cell;
// Get the neighbor cell in (x, y)
// NB: cellVec has been filled up earlier and contains all the cells
Cell* neighbor = cellVec.at( (y*w) + x );
// The neighbor cell has already been visited
if( neighbor->visited ) return cell;
// The neighbor cell is of the same class as the mother cell
if( neighbor->cClass != cell->cClass ) return cell;
// Set the region number for the neighbor
neighbor->visited = true;
return neighbor;
}
所以这是我的问题:我确信这可以改进,但我想知道如何。我应该使用其他递归吗?如何改进这种递归?我阅读了这篇关于尾调用优化的文章,但由于我无法丢弃调用者的状态,因此无法应用。但是我可以使用其他技巧吗?
感谢您的回答,我希望我已经足够明确了。
注意:如果我有一个单色图像,大小为 640*480,单元格大小为 2*2 像素,我有 153765 个调用。当然还有一个单元格大小为 1*1 的段错误。我知道我可以增加堆栈的大小,但我更愿意找到另一种解决方案。