图像处理

/*************************************************************************
  *
  * 函数名称:
  *   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;
}


你可能感兴趣的:(图像处理)