图像二值化算法

/*************************************************************************

 *

 * 函数名称:

 *   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);

  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;

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值