当前位置: 首页 >> 程序设计 >> 数据结构和算法 >> 图像二值化算法源码
 

图像二值化算法源码

作者:neusoft      来源:neusoft.cublog.cn     发表时间:2006-10-11     浏览次数:      字号:    

/*************************************************************************
 *
 * 函数名称:
 *   ThresholdDIB()
 *
 * 参数:
 *   LPSTR lpDIBBits    - 指向源DIB图像指针
 *   LONG  lWidth       - 源图像宽度(象素数)
 *   LONG  lHeight      - 源图像高度(象素数)
 *
 * 返回值:
 *   BOOL               - 运算成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 * 该函数用于对图像进行阈值分割运算。
 *
 ************************************************************************/
BOOL WINAPI ThresholdDIB(LPSTR lpDIBBits,LONG lWidth, LONG lHeight)
{
 
 // 指向源图像的指针
 LPSTR lpSrc;
 
 // 指向缓存图像的指针
 LPSTR lpDst;
 
 // 指向缓存DIB图像的指针
 LPSTR lpNewDIBBits;
 HLOCAL hNewDIBBits;
 //循环变量
 long i;
 long j;
 //像素值
 unsigned char pixel;
 //直方图数组
 long lHistogram[256];
 //阈值,最大灰度值与最小灰度值,两个区域的平均灰度值
 unsigned char iThreshold,iNewThreshold,iMaxGrayValue,iMinGrayValue,iMean1GrayValue,iMean2GrayValue;
 //用于计算区域灰度平均值的中间变量
 long lP1,lP2,lS1,lS2;
 //迭代次数
 int iIterationTimes;
 // 图像每行的字节数
 LONG lLineBytes;
 // 暂时分配内存,以保存新图像
 hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);
 if (hNewDIBBits == NULL)
 {
  // 分配内存失败
  return FALSE;
 }
 
 // 锁定内存
 lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
 // 初始化新分配的内存,设定初始值为255
 lpDst = (char *)lpNewDIBBits;
 memset(lpDst, (BYTE)255, lWidth * lHeight);
 // 计算图像每行的字节数
 lLineBytes = WIDTHBYTES(lWidth * 8);
 for (i = 0; i < 256;i++)
 {
  lHistogram[i]=0;
 }
 //获得直方图
 iMaxGrayValue = 0;
 iMinGrayValue = 255;
 for (i = 0;i < lWidth ;i++)
 {
  for(j = 0;j < lHeight ;j++)
  {
   // 指向源图像倒数第j行,第i个象素的指针   
   lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
 
   pixel = (unsigned char)*lpSrc;
   
   lHistogram[pixel]++;
   //修改最大,最小灰度值
   if(iMinGrayValue > pixel)
   {
    iMinGrayValue = pixel;
   }
   if(iMaxGrayValue < pixel)
   {
    iMaxGrayValue = pixel;
   }
  }
 }
 //迭代求最佳阈值
 iNewThreshold = (iMinGrayValue + iMaxGrayValue)/2;
 iThreshold = 0;
 
 for(iIterationTimes = 0; iThreshold != iNewThreshold && iIterationTimes < 100;iIterationTimes ++)
 {
  iThreshold = iNewThreshold;
  lP1 =0;
  lP2 =0;
  lS1 = 0;
  lS2 = 0;
  //求两个区域的灰度平均值
  for (i = iMinGrayValue;i < iThreshold;i++)
  {
   lP1 += lHistogram[i]*i;
   lS1 += lHistogram[i];
  }
  iMean1GrayValue = (unsigned char)(lP1 / lS1);
  for (i = iThreshold+1;i < iMaxGrayValue;i++)
  {
   lP2 += lHistogram[i]*i;
   lS2 += lHistogram[i];
  }
  iMean2GrayValue = (unsigned char)(lP2 / lS2);
  iNewThreshold =  (iMean1GrayValue + iMean2GrayValue)/2;
 }
 //根据阈值将图像二值化
 for (i = 0;i < lWidth ;i++)
 {
  for(j = 0;j < lHeight ;j++)
  {
   // 指向源图像倒数第j行,第i个象素的指针   
   lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
 
   // 指向目标图像倒数第j行,第i个象素的指针   
   lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;
   pixel = (unsigned char)*lpSrc;
   
   if(pixel <= iThreshold)
   {
    *lpDst = (unsigned char)0;
   }
   else
   {
    *lpDst = (unsigned char)255;
   }
  }
 }
 // 复制图像
 memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
 // 释放内存
 LocalUnlock(hNewDIBBits);
 LocalFree(hNewDIBBits);
 // 返回
 return TRUE;
}

责任编辑 webmaster

 
 
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •