通常,在二值图中,我们通过连通域算法,找到图像中各个独立的封闭区间,甚至提取其轮廓特征,为目标识别和追踪提供了思路。而连通域算法一般有4-连通域和8-连通域两种定义。4-连通域指以检测点为中心的上下左右4个方向为其可能连通域,8-连通域指以监测点为中心的上下左右,左上,右上,左下,右下8个方向为其可能连通域。
#include <iostream>
using namespace std;
int m, n;
int **map;
int **map1;
static int t = 0;
void Input();
int GetPartNum();
void Clear(int x, int y, int num);
int main()
{
Input();
int num = GetPartNum();
cout << num << endl;
cout << t << endl;
for (int i = 0; i < m; ++i)
{
cout << endl;
for (int j = 0; j < n; ++j)
{
cout << map1[i][j];
}
}
for (int i = 0; i < m; ++i)
{
delete [] map[i];
delete [] map1[i];
}
system("pause");
return 0;
}
//输入二值图像
void Input()
{
cin >> m >> n;
map = new int* [m];
map1 = new int*[m];
for (int i = 0; i < m; ++i)
{
map[i] = new int[n];
map1[i] = new int[n];
for (int j = 0; j < n; ++j)
{
cin >> map[i][j];
map1[i][j] = 0;
}
}
}
int GetPartNum()
{
int num = 0;
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (map[i][j]==1)//如果坐标(i,j)值为1
{
num++;
Clear(i, j, num);
}
}
}
return num;
}
void Clear(int x, int y, int num)
{
int xx, yy;
map[x][y] = 0;
map1[x][y] = num;
for (int i = -1; i < 2; ++i)//i=[-1,0,1];
{
for (int j = -1; j < 2; ++j)//i=[-1,0,1];
{
t++;//循环计数
if (i == 0 && j == 0) continue;
xx = x + i;
yy = y + j;
if (xx >= 0 && xx < m && yy >= 0 && yy < n && map[xx][yy]==1)//使用递归,将8领域为1的点置0
Clear(xx, yy, num);
}
}
}
这里我首先计算0,1二值数组中的连通域:
此方法思路简单,易于编码,但是重复计算多,效率不高。