1. 程式人生 > >影象連通域計算問題

影象連通域計算問題

通常,在二值圖中,我們通過連通域演算法,找到影象中各個獨立的封閉區間,甚至提取其輪廓特徵,為目標識別和追蹤提供了思路。而連通域演算法一般有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)
	{
		free(map[i]);
		free(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二位陣列中的連通域:

此方法思路簡單,易於編碼,但是重複計算多,效率不高。