连接组件不适用于大矩阵大小

时间:2014-03-30 07:17:20

标签: c++ image-processing

我有这个代码,用于在二进制图像中查找所有连接的组件以及该组件中的总像素数。

int isSafe(unsigned char *M, int row, int col, bool visited[][COL])
{
    return (row >= 0) && (row < ROW) && (col >= 0) && (col < COL) &&     
       (M[row*ROW + col] && !visited[row][col]); 
}

void DFS(unsigned char *M, int row, int col, bool visited[][COL])
{
    indexes.push_back(count_elements);//
    indexes.at(count_elements)= ((row+1)*ROW + col+1);
    ++count_elements;
    //add index positions to array or vector
    static int rowNbr[] = {-1, -1, -1,  0, 0,  1, 1, 1};
    static int colNbr[] = {-1,  0,  1, -1, 1, -1, 0, 1};

    visited[row][col] = true;

    for (int k = 0; k < 8; ++k)
    if (isSafe(M, row + rowNbr[k], col + colNbr[k], visited) )
    {
        DFS(M, row + rowNbr[k], col + colNbr[k], visited);
    }
}

int countComponents(unsigned char *M)
{
    bool visited[ROW][COL];
    memset(visited, 0, sizeof(visited));    

    for (int i = 0; i < ROW; ++i)
    for (int j = 0; j < COL; ++j)
        if (M[i*ROW + j] && !visited[i][j]) 
        {
            //indexes.clear();
            count_elements=0;
            DFS(M, i, j, visited);
            elements[count] = count_elements;
            ++count;                
        }

    /*for (int i = 1; i < ROW; ++i)
    {
    if(elements[0]<elements[i])
        elements[0] = elements[i];      
    }*/
    //printf("%d ", elements[0]);
    return count;
}

M是尺寸为512x512的图像。 elements []存储每个连接组件中的像素总数,索引向量存储连接的像素的索引。如果任何连接组件中的总像素数小于3200(大约),则上面的代码工作正常。但是,如果此值大于3200,则此代码不起作用。请帮帮我。

1 个答案:

答案 0 :(得分:0)

你的堆栈大小不合适。使用Visual Studio的默认设置,即使是只有参数的函数是int,也只能递归4711时间(调试模式,我的电脑)。你传递了更多的参数,并且你在堆栈上放了很多数据(bool访问了[ROW] [COL] - 或许更多的是你未发布的代码)。因此,在对DFS进行几千次递归调用后,您将获得堆栈溢出(尽管实际崩溃可能出现在new()中)。 一些替代解决方案:

  1. 通过命令行或链接器选项更改堆栈大小。这是高度未经证实的

  2. 使用向量作为堆栈(直接或使用std :: stack adapter)而不是递归。这意味着,DPS不需要递归,只需保留未开发点的向量,取最后一个,找到所有未访问的邻居,使用emplace_back等等。

  3. 使用更好的连通分量算法