ð

来自「区域增长的算法实现: 1)根据图像的不同应用选择一个或一组种 子,它或者是最亮或」· 代码 · 共 131 行

TXT
131
字号
/*************************************************************************
 * \函数名称:
 *   RegionGrow()
 * 参数:
 *   LPSTR lpDIBBits    - 指向源DIB图像指针
 *   LONG  lmageWidth       - 源图像宽度(象素数,必须是4的倍数)
 *   LONG  lmageHeight      - 源图像高度(象素数)
 *	 int nThreshold			- 区域生长门限
 *	 int seedx				- 区域生长种子的横坐标
 *	 int seedy				- 区域生长种子的纵坐标
  *	 int mode				- 区域生长种子的选取类型
 * 返回值:
 *   BOOL               - 运算成功返回TRUE,否则返回FALSE。
 * \说明:
 *   本函数的处理结果是将生长后的区域表示为黑色像素,未生长区域表示为白色像素。
 *   区域生长一般包含三个比较重要的问题:
 *		1. 种子点的选取
 *		2. 生长准则
 *		3. 终止条件
 *	 可以认为,这三个问题需要具体分析,而且每个问题解决的好坏直接关系到
 *	 区域生长的结果。
 *************************************************************************/
BOOL RegionGrow(LPSTR lpDIBBits, LONG lmageWidth, LONG lmageHeight, int nThreshold,int seedx,int seedy,int mode)
{	
	//设置用于处理四临域的数组
	static int Dx[]={-1,0,1,0};	//X向
	static int Dy[]={0,1,0,-1};	//y向
	// 临时存放图像数据的指针
	LPBYTE			lpImage;	
	// 指向源图像的指针
	unsigned char*	lpSrc;
	unsigned char*	lpSrc1;
	// 指向要复制区域的指针
	unsigned char*	lpDst;
	// 分配内存
	lpImage = (LPBYTE) new  char[lmageWidth*lmageHeight];	
	// 判断是否内存分配失败
	if (lpImage == NULL)
	{
		// 分配内存失败
		return FALSE;
	}
	// 将目标图像所有像素初始化为白点
	lpDst = (unsigned char *)lpImage;
	memset(lpDst, (BYTE)255, lmageWidth * lmageHeight);
	// 种子点
	CPoint seed;
	if(mode==0) // 如果选择种子点为图像的中心
	{
		// 设置种子点为图像的中心
		seed.x=lmageWidth/2;
		seed.y=lmageHeight/2;
	}
	else //自己设置种子点
	{
		// 设置种子点为输入点
		seed.x=seedx;
		seed.y=seedy;
	}

	// 定义堆栈,分别存贮X Y坐标
	int * GrowX ;
	int * GrowY ;
	
	// 分配空间,最大为图像的像素数目
	GrowX = new int [ lmageWidth * lmageHeight];
	GrowY = new int [ lmageWidth * lmageHeight];

	
	// 定义堆栈的起点和终点
	// 当Start=End, 表示堆栈中只有一个点
	int Start ;
	int End   ;
	//初始化
	Start = 0 ;
	End   = 0 ;
	// 把种子点的坐标压入栈
	GrowX[End] = seed.x;
	GrowY[End] = seed.y;
	// 当前正在处理的象素
	CPoint Current;
	// 循环控制变量
	int k ;
	// 图象的横纵坐标,用来对当前象素的4邻域进行遍历
	int xx;
	int yy;
	while (Start<=End)
	{
		// 当前种子点的坐标
		Current.x = GrowX[Start];
		Current.y = GrowY[Start];
		// 对当前点的4邻域进行遍历
		for (k=0; k<4; k++)	
		{	
			// 4邻域象素的坐标
			xx = Current.x+Dx[k];
			yy = Current.y+Dy[k];
			
			// 判断象素(xx,yy) 是否在图像内部
			// 判断象素(xx,yy) 是否已经处理过
			// *lpDst==255 表示还没有处理
			// 指向源图像(xx,yy)象素的指针			
			lpSrc = (unsigned char *)lpDIBBits + lmageWidth * (lmageHeight-yy) + xx;
			lpSrc1 = (unsigned char *)lpDIBBits + lmageWidth * (lmageHeight-Current.y) + Current.x;
			// 指向目标图像第j行,第i个象素的指针			
			lpDst = (unsigned char *)lpImage + lmageWidth * (lmageHeight-yy) + xx;
			// 生长条件:判断象素(xx,yy)和当前象素(nCurrX,nCurrY) 象素值差的绝对值
			if ((xx < lmageWidth) && (xx>=0) && (yy<lmageHeight) && (yy>=0) && (*lpDst==255) 
					&& abs(*lpSrc-*lpSrc1)<nThreshold )
			{
				// 堆栈的尾部指针后移一位
				End++;
				// 象素(xx,yy) 压入栈
				GrowX[End] = xx;
				GrowY[End] = yy;
				// 目标图像为黑点,同时也表明该象素处理过
				*lpDst=0 ;
			}
		}
		Start++;
	}
	// 复制区域生长后的图像
	memcpy(lpDIBBits, lpImage, lmageWidth * lmageHeight);
	// 释放内存
	delete[] lpImage;
	delete[] GrowX;
	delete[] GrowY;
	// 返回
	return TRUE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?