【问题标题】:How do I find the connected components in a binary image?如何在二进制图像中找到连接的组件?
【发布时间】:2014-03-29 20:27:40
【问题描述】:

我正在寻找一种算法来查找我的二进制图像中的所有连通分量。

如果我们把图像想象成一个矩阵,它看起来像:

[ 0 0 0 0 ...
  0 0 0 0 ...
  0 1 1 1 ...
  0 1 0 1 ...
  0 1 0 0 ...
  ...
]

我想找到所有接触的(对角线也是如此)。在此示例中,只有一个组件 - 但图像中可能有数百个独特的组件。

Image => ALGORITHM => [ [(x,y)], ... ] 
                      # list of lists of coordinates (each shape is a list)

我查看了 Wikipedia 上的 two pass labelling 算法,但我不相信它会返回实际的组件 - 它只是标记不同的组件。 (或者这个是一样的吗?)

如果可能,这应该能够针对视频流实时运行。

【问题讨论】:

  • 两遍就好了。将它们全部标记后,只需遍历它们并按标签将它们添加到单独的列表中。本质上,让它三遍:)
  • 我的想法是连接组件标签(CCL)很好,@Geobits 是对的,一旦你得到了这些组件的标签,后处理就不是问题(就复杂性而言)。我在想的是,实际上CCL似乎有点矫枉过正..不是一个简单的DFS可以标记所有具有相同复杂性的组件吗?
  • @shole DFS,你的意思是深度优先搜索?如何将图像放入图表以执行 DFS?
  • @JimMischel 如何为多个组件执行泛洪填充?

标签: algorithm language-agnostic computer-vision image-recognition


【解决方案1】:

下面是一个简单的代码(C++),使用简单的dfs来标记不同的组件,你可以试试看。

例如,如果您的标准输入是

4 5
0 0 0 0 1
0 1 1 0 1
0 0 1 0 0
1 0 0 0 1

那么输出应该是

Graph:
0 0 0 0 1 
0 1 1 0 1 
0 0 1 0 0 
1 0 0 0 1 

Output:
0 0 0 0 1 
0 2 2 0 1 
0 0 2 0 0 
3 0 0 0 4

相同的数字代表该单元属于同一个组件。

我假设所有 8 个方向都属于同一个组件,如果你只想要 4 个方向, 改变 dx[] 和 dy[]

另外我假设输入最多为 200*200,我做了一些事情来避免处理那些烦人的数组出站问题,你可以检查一下 :)

#include<cstdio>
#include<cstdlib>
#include<cstring>

int g[202][202] = {0};
int w[202][202] = {0};

int dx[8] = {-1,0,1,1,1,0,-1,-1};
int dy[8] = {1,1,1,0,-1,-1,-1,0};

void dfs(int x,int y,int c){
    w[x][y] = c;
    for(int i=0; i<8;i++){
        int nx = x+dx[i], ny = y+dy[i];
        if(g[nx][ny] && !w[nx][ny]) dfs(nx,ny,c);
    }
}

int main(){
    int row, col, set = 1;
    scanf("%d%d", &row, &col);

    for(int i=1; i<=row; i++) for(int j=1; j<=col; j++) scanf("%d", &g[i][j]);

    for(int i=1; i<=row;i++)
        for(int j=1; j<=col; j++)
            if(g[i][j] && !w[i][j])
                dfs(i,j,set++);

    printf("Graph:\n");
    for(int i=1; i<=row;i++){
        for(int j=1; j<=col;j++)
            printf("%d ", g[i][j]);
        puts("");
    }
    puts("");
    printf("Output:\n");
    for(int i=1; i<=row;i++){
        for(int j=1; j<=col;j++)
            printf("%d ", w[i][j]);
        puts("");
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 2013-07-08
    • 2015-09-29
    • 2021-05-09
    • 2014-12-07
    • 2021-12-11
    • 1970-01-01
    相关资源
    最近更新 更多