Chinaunix首页 | 论坛 | 博客
  • 博客访问: 292864
  • 博文数量: 109
  • 博客积分: 2116
  • 博客等级: 大尉
  • 技术积分: 1062
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-22 15:38
文章分类

全部博文(109)

文章存档

2013年(2)

2011年(16)

2010年(90)

2009年(1)

我的朋友

分类:

2010-08-01 10:15:37

/*************************************************************************
 *
 * 函数名称:
 *   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<2; iAngleNumber++)
  {
   if(iDist+MaxValue1.Dist>=0 && iDist+MaxValue1.Dist    && iAngleNumber+MaxValue1.AngleNumber>=0 && iAngleNumber+MaxValue1.AngleNumber<=iMaxAngleNumber)
   {
    *(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)<=2)
 {
  //两直线平行,在缓存图像中重绘这两条直线
  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;
}
阅读(424) | 评论(0) | 转发(0) |
0

上一篇:逆滤波

下一篇:快速沃尔什-哈达玛变换

给主人留下些什么吧!~~