MFC图像处理源代码总集

源代码在线查看: hough变换.txt

软件大小: 8625 K
上传用户: pc1667pc1667
关键词: MFC 图像处理 源代码
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*************************************************************************
				 *
				 * 函数名称:
				 *   HoughDIB()
				 *
				 * 参数:
				 *   LPSTR lpDIBBits    - 指向源DIB图像指针
				 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数)
				 *   LONG  lHeight      - 源图像高度(象素数)
				 * 返回值:
				 *   BOOL               - 运算成功返回TRUE,否则返回FALSE。
				 *
				 * 说明:
				 * 该函数用于对检测图像中的平行直线。如果图像中有两条平行的直线,则将这两条平行直线
				 * 提取出来。
				 * 
				 * 要求目标图像为只有0和255两个灰度值的灰度图像。
				 ************************************************************************/
				
				BOOL WINAPI HoughDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
				{
						
					// 指向源图像的指针
					LPSTR	lpSrc;
					
					// 指向缓存图像的指针
					LPSTR	lpDst;
					
					// 指向变换域的指针
					LPSTR   lpTrans;
				
					// 图像每行的字节数
					LONG lLineBytes;
					
					// 指向缓存DIB图像的指针
					LPSTR	lpNewDIBBits;
					HLOCAL	hNewDIBBits;
				
					//指向变换域的指针
					LPSTR	lpTransArea;
					HLOCAL	hTransArea;
				
					//变换域的尺寸
					int iMaxDist;
					int iMaxAngleNumber;
				
					//变换域的坐标
					int iDist;
					int iAngleNumber;
				
					//循环变量
					long i;
					long j;
				
					//像素值
					unsigned char pixel;
				
					//存储变换域中的两个最大值
					MaxValue MaxValue1;
					MaxValue MaxValue2;
				
					// 暂时分配内存,以保存新图像
					hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);
				
					if (hNewDIBBits == NULL)
					{
						// 分配内存失败
						return FALSE;
					}
					
					// 锁定内存
					lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
				
					// 初始化新分配的内存,设定初始值为255
					lpDst = (char *)lpNewDIBBits;
					memset(lpDst, (BYTE)255, lWidth * lHeight);
				
					//计算变换域的尺寸
					//最大距离
					iMaxDist = (int) sqrt(lWidth*lWidth + lHeight*lHeight);
				
					//角度从0-180,每格2度
					iMaxAngleNumber = 90;
				
					//为变换域分配内存
					hTransArea = LocalAlloc(LHND, lWidth * lHeight * sizeof(int));
				
					if (hNewDIBBits == NULL)
					{
						// 分配内存失败
						return FALSE;
					}
					
					// 锁定内存
					lpTransArea = (char * )LocalLock(hTransArea);
						
					// 初始化新分配的内存,设定初始值为0
					lpTrans = (char *)lpTransArea;
					memset(lpTrans, 0, lWidth * lHeight * sizeof(int));
				
					// 计算图像每行的字节数
					lLineBytes = WIDTHBYTES(lWidth * 8);
				
					for(j = 0; j 					{
						for(i = 0;i 						{
				
							// 指向源图像倒数第j行,第i个象素的指针			
							lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
				
							//取得当前指针处的像素值,注意要转换为unsigned char型
							pixel = (unsigned char)*lpSrc;
				
							//目标图像中含有0和255外的其它灰度值
							if(pixel != 255 && *lpSrc != 0)
								return FALSE;
				
							//如果是黑点,则在变换域的对应各点上加1
							if(pixel == 0)
							{
								//注意步长是2度
								for(iAngleNumber=0; iAngleNumber								{
									iDist = (int) fabs(i*cos(iAngleNumber*2*pi/180.0) + \
										j*sin(iAngleNumber*2*pi/180.0));
								
									//变换域的对应点上加1
									*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber) = \
										*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber) +1;
								}
							}
						
						}
					}
								
					//找到变换域中的两个最大值点
					MaxValue1.Value=0;
					MaxValue2.Value=0;
					
					//找到第一个最大值点
					for (iDist=0; iDist					{
						for(iAngleNumber=0; iAngleNumber						{
							if((int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber)>MaxValue1.Value)
							{
								MaxValue1.Value = (int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber);
								MaxValue1.Dist = iDist;
								MaxValue1.AngleNumber = iAngleNumber;
							}
				
						}
					}
				
					//将第一个最大值点附近清零
					for (iDist = -9;iDist < 10;iDist++)
					{
						for(iAngleNumber=-1; iAngleNumber						{
							if(iDist+MaxValue1.Dist>=0 && iDist+MaxValue1.Dist								&& iAngleNumber+MaxValue1.AngleNumber>=0 && iAngleNumber+MaxValue1.AngleNumber							{
								*(lpTransArea+(iDist+MaxValue1.Dist)*iMaxAngleNumber+\
									(iAngleNumber+MaxValue1.AngleNumber))=0;
							}
						}
					}
				
					//找到第二个最大值点
					for (iDist=0; iDist					{
						for(iAngleNumber=0; iAngleNumber						{
							if((int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber)>MaxValue2.Value)
							{
								MaxValue2.Value = (int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber);
								MaxValue2.Dist = iDist;
								MaxValue2.AngleNumber = iAngleNumber;
							}
				
						}
					}
				
				
					//判断两直线是否平行
					if(abs(MaxValue1.AngleNumber-MaxValue2.AngleNumber)					{
						//两直线平行,在缓存图像中重绘这两条直线
						for(j = 0; j 						{
							for(i = 0;i 							{	
				
								// 指向缓存图像倒数第j行,第i个象素的指针			
								lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;	
				
								//如果该点在某一条平行直线上,则在缓存图像上将该点赋为黑
				
								//在第一条直线上
								iDist = (int) fabs(i*cos(MaxValue1.AngleNumber*2*pi/180.0) + \
											j*sin(MaxValue1.AngleNumber*2*pi/180.0));
								if (iDist == MaxValue1.Dist)
									*lpDst = (unsigned char)0;
							
								//在第二条直线上
								iDist = (int) fabs(i*cos(MaxValue2.AngleNumber*2*pi/180.0) + \
											j*sin(MaxValue2.AngleNumber*2*pi/180.0));
								if (iDist == MaxValue2.Dist)
									*lpDst = (unsigned char)0;
							}
						}
					}
				
					// 复制腐蚀后的图像
					memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
				
					// 释放内存
					LocalUnlock(hNewDIBBits);
					LocalFree(hNewDIBBits);
				
					// 释放内存
					LocalUnlock(hTransArea);
					LocalFree(hTransArea);
				
					// 返回
					return TRUE;
				
				}
							

相关资源