水蔚如蓝
C++学习者
posts - 0,  comments - 1,  trackbacks - 0
/*************************************************************************
 *
 * 函数名称:
 *   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;
}
posted on 2006-10-11 10:52 晴天没云 阅读(1885) 评论(0)  编辑 收藏 引用 所属分类: VC++学习

<2025年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿

文章分类

文章档案

搜索

  •  

最新评论