www.pudn.com > erosion.zip > erosion.cpp


/************************************************************************* 
 * 
 * 函数名称: 
 *   VHErosion() 
 * 
 * 参数: 
 *   HDIB hDIB          - 待处理的DIB 
 * 
 * 返回值: 
 *   void				- 无返回值 
 * 
 * 说明: 
 *   该函数对图象进行全方向腐蚀 
 * 
 ************************************************************************/ 
void CMorph::Erosion(HDIB hDIB) 
{ 
	//循环变量 
	LONG i; 
	LONG j; 
	LONG m; 
	LONG n; 
 
	// 指向DIB的指针 
	LPBYTE lpDIB; 
	 
	// 指向DIB象素指针 
	LPBYTE lpDIBBits; 
	 
	// 指向源图像的指针 
	LPBYTE	lpSrc; 
	 
	// 指向缓存图像的指针 
	LPBYTE	lpDst; 
 
	// 指向缓存DIB图像的指针 
	LPBYTE	lpNewDIBBits; 
	HLOCAL	hNewDIBBits; 
 
	// 锁定DIB 
	lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB); 
 
	// 找到DIB图像象素起始位置 
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB); 
	 
	// 判断是否是24-bpp位图 
	if (m_clsDIB.DIBBitCount(lpDIB) != 24) 
	{ 
		// 提示用户 
		MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
		 
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) hDIB); 
		 
		// 返回 
		return; 
	} 
	 
	// 更改光标形状 
	BeginWaitCursor(); 
	 
	// DIB的宽度 
	LONG lWidth = m_clsDIB.DIBWidth(lpDIB); 
	 
	// DIB的高度 
	LONG lHeight = m_clsDIB.DIBHeight(lpDIB); 
	 
	// 计算图像每行的字节数 
	LONG lLineBytes = WIDTHBYTES(lWidth * 24); 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); 
 
	if (hNewDIBBits == NULL) 
	{ 
		// 分配内存失败 
		return; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits = (LPBYTE)LocalLock(hNewDIBBits); 
 
	// 初始化新分配的内存,设定初始值为255 
	lpDst = (LPBYTE)lpNewDIBBits; 
	memset(lpDst, (BYTE)255, lLineBytes * lHeight); 
 
	// 3×3的结构元素 
	int T[9] = {1, 1, 1, 
				1, 1, 1, 
				1, 1, 1}; 
 
	// 使用水平方向的结构元素进行腐蚀 
	for (i = 1; i < lHeight - 1; i++) 
	{ 
		for (j = 3; j < lLineBytes - 3; j += 3) 
		{ 
			// 由于使用3×3的结构元素,为防止越界,所以不处理最左、右、上、下四边的像素 
			 
			// 指向源图像倒数第j行,第i个象素的指针			 
			lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + j); 
 
			// 指向目标图像倒数第j行,第i个象素的指针			 
			lpDst = (unsigned char *)(lpNewDIBBits + lLineBytes * i + j); 
 
			// 目标图像中的当前点先赋成黑色 
			*lpDst = 0; 
			*(lpDst + 1) = 0; 
			*(lpDst + 2) = 0; 
  
			// 如果源图像中3×3结构元素对应位置有白点	 
			// 则将目标图像中的(0,0)点赋成白色 
			for (m = 0; m < 3; m++) 
			{ 
				for (n = 0; n < 3; n++) 
				{ 
					if (T[m * 3 + n] == 0) 
						continue; 
 
					if (*(lpSrc + (1 - m) * lLineBytes +(n - 1) * 3) > 128) 
					{ 
						*lpDst = 255; 
						*(lpDst + 1) = 255; 
						*(lpDst + 2) = 255; 
						break; 
					} 
				} 
			}				 
		} 
	} 
	// 复制腐蚀后的图像 
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); 
 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) hDIB); 
 
	// 释放内存 
	LocalUnlock(hNewDIBBits); 
	LocalFree(hNewDIBBits); 
 
	// 恢复光标 
	EndWaitCursor(); 
}