⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edgecontour.cpp

📁 vc++数字图像处理 ,是一本很不错的介绍数字图像方面的书籍,这里有本书的全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	// 返回	return TRUE;}/************************************************************************* * * 函数名称: *   Fill2DIB() * * 参数: *   LPSTR lpDIBBits    - 指向源DIB图像指针 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) *   LONG  lHeight      - 源图像高度(象素数) * 返回值: *   BOOL               - 种子填充成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用于对图像进行种子填充运算。 *  * 要求目标图像为只有0和255两个灰度值的灰度图像。 ************************************************************************/BOOL WINAPI Fill2DIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight){		// 指向源图像的指针	LPSTR	lpSrc;	//循环变量	long i;	//像素值	unsigned char pixel;	//左右边界像素位置	int xl,xr;	//是否已填充至边界	BOOL bFilll,bFillr;	//种子堆栈及指针	Seed Seeds[10];	int StackPoint;	//当前像素位置	int iCurrentPixelx,iCurrentPixely;	int iBufferPixelx,iBufferPixely;	//初始化种子	Seeds[1].Height = lHeight / 2;	Seeds[1].Width = lWidth / 2;	StackPoint = 1;	while( StackPoint != 0)	{		//取出种子		iCurrentPixelx = Seeds[StackPoint].Width;		iCurrentPixely = Seeds[StackPoint].Height;		StackPoint--;//		if(Seed2.Height== 75)//		{//			return true;//			i++;//		}		bFilll = true;		bFillr = true;		//填充种子所在的行		//保存种子像素的位置		iBufferPixelx = iCurrentPixelx;		iBufferPixely = iCurrentPixely;		//先向左填充		while(bFilll)		{			lpSrc = (char *)lpDIBBits + lWidth * iCurrentPixely + iCurrentPixelx;			//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			//目标图像中含有0和255外的其它灰度值			if(pixel != 255 && pixel != 0)				return FALSE;			//遇到边界			if(pixel == 0)			{				bFilll = false;				xl=iCurrentPixelx+1;			}			else			{				*lpSrc = (unsigned char)0;				iCurrentPixelx--;				//防止越界				if(iCurrentPixelx<0)				{						bFilll = false;					iCurrentPixelx = 0;					xl = 0; 				}			}				}		//再向右填充		//取回种子像素的位置		iCurrentPixelx = iBufferPixelx+1;		if(iCurrentPixelx>lWidth)		{				bFillr = false;			iCurrentPixelx = lWidth;			xr = lWidth; 		}		iCurrentPixely = iBufferPixely;		while(bFillr)		{			lpSrc = (char *)lpDIBBits + lWidth * iCurrentPixely + iCurrentPixelx;			//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			//目标图像中含有0和255外的其它灰度值			if(pixel != 255 && pixel != 0)				return FALSE;			//遇到边界			if(pixel == 0)			{				bFillr = false;				xr=iCurrentPixelx-1;			}			else			{				*lpSrc = (unsigned char)0;				iCurrentPixelx++;				//防止越界				if(iCurrentPixelx>lWidth)				{						bFillr = false;					iCurrentPixelx = lWidth;					xr = lWidth; 				}			}				}		//上、下两条扫描线是否全为边界象素或已填充过		//先看上面的扫描线		iCurrentPixely--;		if(iCurrentPixely < 0)		{			iCurrentPixely = 0;		}		for (i = xr; i>= xl;i--)		{			lpSrc = (char *)lpDIBBits + lWidth * iCurrentPixely + i;			//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			//有未填充的像素,将新的种子压入堆栈			if (pixel == 255)			{				StackPoint++;				Seeds[StackPoint].Height = iCurrentPixely;				Seeds[StackPoint].Width = i;				break;			}						}		//再看下面的扫描线		iCurrentPixely+=2;		if(iCurrentPixely > lHeight)		{			iCurrentPixely = lHeight;		}		for (i = xr; i>= xl;i--)		{			lpSrc = (char *)lpDIBBits + lWidth * iCurrentPixely + i;			//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			//有未填充的像素,将新的种子压入堆栈			if (pixel == 255)			{				StackPoint++;				Seeds[StackPoint].Height = iCurrentPixely;				Seeds[StackPoint].Width = i;				break;			}						}	}	// 返回	return TRUE;}/************************************************************************* * * 函数名称: *   FillDIB() * * 参数: *   LPSTR lpDIBBits    - 指向源DIB图像指针 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) *   LONG  lHeight      - 源图像高度(象素数) * 返回值: *   BOOL               - 种子填充成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用于对图像进行种子填充运算。 *  * 要求目标图像为只有0和255两个灰度值的灰度图像。 ************************************************************************/BOOL WINAPI FillDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight){		// 指向源图像的指针	LPSTR	lpSrc;	//像素值	unsigned char pixel;	//种子堆栈及指针	Seed *Seeds;	int StackPoint;	//当前像素位置	int iCurrentPixelx,iCurrentPixely;	//初始化种子	Seeds = new Seed[lWidth*lHeight];	Seeds[1].Height = lHeight / 2;	Seeds[1].Width = lWidth / 2;	StackPoint = 1;	while( StackPoint != 0)	{		//取出种子		iCurrentPixelx = Seeds[StackPoint].Width;		iCurrentPixely = Seeds[StackPoint].Height;		StackPoint--;		lpSrc = (char *)lpDIBBits + lWidth * iCurrentPixely + iCurrentPixelx;		//取得当前指针处的像素值,注意要转换为unsigned char型		pixel = (unsigned char)*lpSrc;		//目标图像中含有0和255外的其它灰度值		if(pixel != 255 && pixel != 0)			return FALSE;		//将当前点涂黑		*lpSrc = (unsigned char)0;		//判断左面的点,如果为白,则压入堆栈		//注意防止越界		if(iCurrentPixelx > 0)		{			lpSrc = (char *)lpDIBBits + lWidth * iCurrentPixely + iCurrentPixelx - 1;			//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			if (pixel == 255)			{				StackPoint++;				Seeds[StackPoint].Height = iCurrentPixely;				Seeds[StackPoint].Width = iCurrentPixelx - 1;			}			//目标图像中含有0和255外的其它灰度值			if(pixel != 255 && pixel != 0)				return FALSE;		}		//判断上面的点,如果为白,则压入堆栈		//注意防止越界		if(iCurrentPixely < lHeight - 1)		{			lpSrc = (char *)lpDIBBits + lWidth * (iCurrentPixely + 1) + iCurrentPixelx;			//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			if (pixel == 255)			{				StackPoint++;				Seeds[StackPoint].Height = iCurrentPixely + 1;				Seeds[StackPoint].Width = iCurrentPixelx;			}			//目标图像中含有0和255外的其它灰度值			if(pixel != 255 && pixel != 0)				return FALSE;		}		//判断右面的点,如果为白,则压入堆栈		//注意防止越界		if(iCurrentPixelx < lWidth - 1)		{			lpSrc = (char *)lpDIBBits + lWidth * iCurrentPixely + iCurrentPixelx + 1;			//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			if (pixel == 255)			{				StackPoint++;				Seeds[StackPoint].Height = iCurrentPixely;				Seeds[StackPoint].Width = iCurrentPixelx + 1;			}			//目标图像中含有0和255外的其它灰度值			if(pixel != 255 && pixel != 0)				return FALSE;		}		//判断下面的点,如果为白,则压入堆栈		//注意防止越界		if(iCurrentPixely > 0)		{			lpSrc = (char *)lpDIBBits + lWidth * (iCurrentPixely - 1) + iCurrentPixelx;			//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			if (pixel == 255)			{				StackPoint++;				Seeds[StackPoint].Height = iCurrentPixely - 1;				Seeds[StackPoint].Width = iCurrentPixelx;			}			//目标图像中含有0和255外的其它灰度值			if(pixel != 255 && pixel != 0)				return FALSE;		}	}	//释放堆栈	delete Seeds;	// 返回	return TRUE;}/************************************************************************* * * 函数名称: *   ContourDIB() * * 参数: *   LPSTR lpDIBBits    - 指向源DIB图像指针 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) *   LONG  lHeight      - 源图像高度(象素数) * 返回值: *   BOOL               - 运算成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用于对图像进行轮廓提取运算。 *  * 要求目标图像为只有0和255两个灰度值的灰度图像。 ************************************************************************/BOOL WINAPI ContourDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight){		// 指向源图像的指针	LPSTR	lpSrc;		// 指向缓存图像的指针	LPSTR	lpDst;		// 指向缓存DIB图像的指针	LPSTR	lpNewDIBBits;	HLOCAL	hNewDIBBits;	//循环变量	long i;	long j;	unsigned char n,e,s,w,ne,se,nw,sw;	//像素值	unsigned char pixel;	// 暂时分配内存,以保存新图像	hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);	if (hNewDIBBits == NULL)	{		// 分配内存失败		return FALSE;	}		// 锁定内存	lpNewDIBBits = (char * )LocalLock(hNewDIBBits);	// 初始化新分配的内存,设定初始值为255	lpDst = (char *)lpNewDIBBits;	memset(lpDst, (BYTE)255, lWidth * lHeight);	for(j = 1; j <lHeight-1; j++)	{		for(i = 1;i <lWidth-1; i++)		{						// 指向源图像倒数第j行,第i个象素的指针						lpSrc = (char *)lpDIBBits + lWidth * j + i;						// 指向目标图像倒数第j行,第i个象素的指针						lpDst = (char *)lpNewDIBBits + lWidth * j + i;						//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;			//目标图像中含有0和255外的其它灰度值//			if(pixel != 255 && pixel != 0)//				return FALSE;			if(pixel == 0)			{				*lpDst = (unsigned char)0;				nw = (unsigned char)*(lpSrc + lWidth -1);				n  = (unsigned char)*(lpSrc + lWidth );				ne = (unsigned char)*(lpSrc + lWidth +1);				w = (unsigned char)*(lpSrc -1);				e = (unsigned char)*(lpSrc +1);				sw = (unsigned char)*(lpSrc - lWidth -1);				s  = (unsigned char)*(lpSrc - lWidth );				se = (unsigned char)*(lpSrc - lWidth +1);				//如果相邻的八个点都是黑点				if(nw+n+ne+w+e+sw+s+se==0)				{					*lpDst = (unsigned char)255;				}			}		}	}	// 复制腐蚀后的图像	memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);	// 释放内存	LocalUnlock(hNewDIBBits);	LocalFree(hNewDIBBits);	// 返回	return TRUE;}/************************************************************************* * * 函数名称: *   TraceDIB() * * 参数: *   LPSTR lpDIBBits    - 指向源DIB图像指针 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) *   LONG  lHeight      - 源图像高度(象素数) * 返回值: *   BOOL               - 运算成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用于对图像进行轮廓跟踪运算。 *  * 要求目标图像为只有0和255两个灰度值的灰度图像。 ************************************************************************/BOOL WINAPI TraceDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight){		// 指向源图像的指针	LPSTR	lpSrc;		// 指向缓存图像的指针	LPSTR	lpDst;		// 指向缓存DIB图像的指针	LPSTR	lpNewDIBBits;	HLOCAL	hNewDIBBits;	// 图像每行的字节数	LONG lLineBytes;		//循环变量	long i;	long j;	//像素值	unsigned char pixel;	//是否找到起始点及回到起始点	bool bFindStartPoint;	//是否扫描到一个边界点	bool bFindPoint;	//起始边界点与当前边界点	Point StartPoint,CurrentPoint;	//八个方向和起始扫描方向	int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};	int BeginDirect;	// 计算图像每行的字节数	lLineBytes = WIDTHBYTES(lWidth * 8);	// 暂时分配内存,以保存新图像	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);	if (hNewDIBBits == NULL)	{		// 分配内存失败		return FALSE;	}		// 锁定内存	lpNewDIBBits = (char * )LocalLock(hNewDIBBits);	// 初始化新分配的内存,设定初始值为255	lpDst = (char *)lpNewDIBBits;	memset(lpDst, (BYTE)255, lLineBytes * lHeight);	//先找到最左上方的边界点	bFindStartPoint = false;	for (j = 0;j < lHeight && !bFindStartPoint;j++)	{		for(i = 0;i < lWidth && !bFindStartPoint;i++)		{			// 指向源图像倒数第j行,第i个象素的指针						lpSrc = (char *)lpDIBBits + lLineBytes * j + i;						//取得当前指针处的像素值,注意要转换为unsigned char型			pixel = (unsigned char)*lpSrc;						if(pixel == 0)			{				bFindStartPoint = true;				StartPoint.Height = j;				StartPoint.Width = i;				// 指向目标图像倒数第j行,第i个象素的指针							lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;					*lpDst = (unsigned char)0;			}				}	}	//由于起始点是在左下方,故起始扫描沿左上方向	BeginDirect = 0;	//跟踪边界	bFindStartPoint = false;	//从初始点开始扫描	CurrentPoint.Height = StartPoint.Height;	CurrentPoint.Width = StartPoint.Width;	while(!bFindStartPoint)	{		bFindPoint = false;		while(!bFindPoint)		{			//沿扫描方向查看一个像素			lpSrc = (char *)lpDIBBits + lLineBytes * ( CurrentPoint.Height + Direction[BeginDirect][1])				+ (CurrentPoint.Width + Direction[BeginDirect][0]);			pixel = (unsigned char)*lpSrc;			if(pixel == 0)			{				bFindPoint = true;				CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];				CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];				if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width)				{					bFindStartPoint = true;				}				lpDst = (char *)lpNewDIBBits + lLineBytes * CurrentPoint.Height + CurrentPoint.Width;				*lpDst = (unsigned char)0;				//扫描的方向逆时针旋转两格				BeginDirect--;				if(BeginDirect == -1)					BeginDirect = 7;				BeginDirect--;				if(BeginDirect == -1)					BeginDirect = 7;			}			else			{				//扫描方向顺时针旋转一格				BeginDirect++;				if(BeginDirect == 8)					BeginDirect = 0;			}		}	}	// 复制腐蚀后的图像	memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);	// 释放内存	LocalUnlock(hNewDIBBits);	LocalFree(hNewDIBBits);	// 返回	return TRUE;}

⌨️ 快捷键说明

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