区域标记

/*ConnectivityMark参数说明:区域标记
ConnectivityMark(
Uchar* ioput,       输入二值图像/输出连通标记图像
int connectType,    连通域类型,只能是:4 or 8(背景标记用4连通,目标标记用8连通)
int* connectArea,   连通区域面积统计(数组大小等于图像)
int* areaNumber,    连通区数量
int rowSize,        图像行数
int colSize,        图像列数
Uchar backFlag,     背景标签
Uchar targetFlag    目标标签
)
*/

static int ConnectivityMark(Uchar* ioput, int connectType, int* connectArea, int* areaNumber, int rowSize, int colSize, Uchar backFlag, Uchar targetFlag)
{
	//connectType=4、8
	int Neighbor[2][8] = {};
	int coordinateNum = connectType;
	if (connectType==4)
	{
		int Neighbor4[2][4] =
		{
			{ -1, 0, 1, 0 },
			{ 0, 1, 0, -1 }
		};
		for (int i = 0; i < 2; i++)
		{
			for (int  j = 0; j < 4; j++)
			{
				Neighbor[i][j] = Neighbor4[i][j];
			}
		}
	}
	else if (connectType == 8)
	{
		int Neighbor8[2][8] =
		{
			{ -1, -1, -1, 0, 0, 1, 1, 1 },
			{ -1, 0, 1, -1, 1, -1, 0, 1 }
		};
		for (int i = 0; i < 2; i++)
		{
			for (int j = 0; j < 8; j++)
			{
				Neighbor[i][j] = Neighbor8[i][j];
			}
		}
	}
	else
	{
		printf(" Error in ConnectivityMark : connectType is not 4 or 8");
		return -1;
	}
	int maxSize = rowSize * colSize;
	int* Q = (int*)malloc(2 * maxSize * sizeof(int));//maxSize * 2数组
	memset(Q, 0, 2 * maxSize  * sizeof(int));
	int front = 0;//指明队头的位置
	int	rear = 0; //指明队尾的下一个位置;front = rear表示队空
	Uchar flag = 0; //连通区标号
	int wide = OFF_BORDER_WIDTH;
	for (int i = wide; i < rowSize - wide; i++)
	{
		for (int j = wide; j < colSize - wide; j++)
		{
			if (ioput[i * colSize + j] == targetFlag)
			{
				if (front == rear)
				{
					flag = flag + 1;
					flag = minf(flag, MAXIMUM_PIXEL_VALUE);//不超过255
				}
				ioput[i * colSize + j] = flag;//给白色像素赋值为连通区域标号
				Q[rear * 2] = i;
				Q[rear * 2 + 1] = j;
				rear = rear + 1; //队尾后移
				while (front != rear)
				{
					//队头出队
					int temp_i = Q[front * 2];
					int temp_j = Q[front * 2 + 1];
					front = front + 1;
					//把队头位置像素点8连通邻域中未作标记的白色像素点入队
					for (int k = 0; k < coordinateNum; k++)
					{
						int y = temp_i + Neighbor[0][k];
						int x = temp_j + Neighbor[1][k];
						if ((y >= 0) & (y < rowSize) & (x >= 0) & (x < colSize))
						{
							if (ioput[y * colSize + x] == targetFlag)
							{
								ioput[y * colSize + x] = flag;
								Q[rear * 2] = y;
								Q[rear * 2 + 1] = x;
								rear = rear + 1;
							}
						}
					}
				}
			}
		}
	}
	*areaNumber = flag;
	for (int i = wide; i < rowSize - wide; i++)
	{
		for (int j = wide; j < colSize - wide; j++)
		{
			if (ioput[i * colSize + j] != backFlag)
			{
				connectArea[ioput[i * colSize + j]] = connectArea[ioput[i * colSize + j]] + 1;
			}
		}
	}
	free(Q);
	Q = NULL;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/u013297911/article/details/88057955