C语言实现对图像的二值化

/*************************************************************************  
    *   该函数用于对图像进行阈值分割运算  
    *   参数:  
    *       LPSTR   lpDIBBits         -   指向源DIB图像指针  
    *       LONG     lWidth               -   源图像宽度(象素数)  
    *       LONG     lHeight             -   源图像高度(象素数)  
    ************************************************************************/  
   
BOOL   ImageChangeProc::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   Threshold,NewThreshold,MaxGrayValue,MinGrayValue,Temp1GrayValue,Temp2GrayValue;  
   
//用于计算区域灰度平均值的中间变量  
long   lP1,lP2,lS1,lS2;  
   
//迭代次数  
int   IterationTimes;  
   
LONG   lLineBytes;  
hNewDIBBits   =   LocalAlloc(LHND,   lWidth   *   lHeight);  
   
if   (hNewDIBBits   ==   NULL)  
{  
//   分配内存失败  
return   FALSE;  
}  
   
//   锁定内存  
lpNewDIBBits   =   (char   *   )LocalLock(hNewDIBBits);  
   
//   初始化新分配的内存  
lpDst   =   (char   *)lpNewDIBBits;  
memset(lpDst,   (BYTE)255,   lWidth   *   lHeight);  
   
lLineBytes   =   WIDTHBYTES(lWidth   *   8);  
   
for   (i   =   0;   i   <   256;i++)  
{  
lHistogram[i]=0;  
}  
   
//获得直方图  
MaxGrayValue   =   0;  
MinGrayValue   =   255;  
for   (i   =   0;i   <   lWidth   ;i++)  
{  
for(j   =   0;j   <   lHeight   ;j++)  
{  
lpSrc   =   (char   *)lpDIBBits   +   lLineBytes   *   j   +   i;  
   
pixel   =   (unsigned   char)*lpSrc;  
   
lHistogram[pixel]++;  
//修改最大,最小灰度值  
if(MinGrayValue   >   pixel)  
{  
MinGrayValue   =   pixel;  
}  
if(MaxGrayValue   <   pixel)  
{  
MaxGrayValue   =   pixel;  
}  
}  
}  
   
//迭代求最佳阈值  
NewThreshold   =   (MinGrayValue   +   MaxGrayValue)/2;  
Threshold   =   0;  
   
for(IterationTimes   =   0;   Threshold   !=   NewThreshold   &&   IterationTimes   <   1000;IterationTimes   ++)  
{  
Threshold   =   NewThreshold;  
lP1   =0;  
lP2   =0;  
lS1   =   0;  
lS2   =   0;  
//求两个区域的灰度平均值  
for   (i   =   MinGrayValue;i   <=Threshold;i++)  
{  
lP1   +=   lHistogram[i]*i;  
lS1   +=   lHistogram[i];  
}  
   
for   (i   =   Threshold+1;i<MaxGrayValue;i++)  
{  
lP2   +=   lHistogram[i]*i;  
lS2   +=   lHistogram[i];  
}  
if(lS1==0||lS2==0)  
{  
//   释放内存  
                          LocalUnlock(hNewDIBBits);  
                          LocalFree(hNewDIBBits);  
                          return   FALSE;  
}  
Temp1GrayValue   =   (unsigned   char)(lP1   /   lS1);  
Temp2GrayValue   =   (unsigned   char)(lP2   /   lS2);  
NewThreshold   =     (Temp1GrayValue   +   Temp2GrayValue)/2;  
}  
   
//根据阈值将图像二值化  
for   (i   =   0;i   <   lWidth   ;i++)  
{  
for(j   =   0;j   <   lHeight   ;j++)  
{  
lpSrc   =   (char   *)lpDIBBits   +   lLineBytes   *   j   +   i;  
lpDst   =   (char   *)lpNewDIBBits   +   lLineBytes   *   j   +   i;  
pixel   =   (unsigned   char)*lpSrc;  
   
if(pixel   <=   Threshold)  
{  
*lpDst   =   (unsigned   char)0;  
}  
else  
{  
*lpDst   =   (unsigned   char)255;  
}  
}  
}  
   
//   复制图像  
memcpy(lpDIBBits,   lpNewDIBBits,   lWidth   *   lHeight);  
   
//   释放内存  
LocalUnlock(hNewDIBBits);  
LocalFree(hNewDIBBits);  
   
//   返回  
return   TRUE;  
}  

http://blog.csdn.net/wdswei/archive/2010/01/05/5128293.aspx

posted on 2010-06-24 09:53  画一个圆圈  阅读(976)  评论(0编辑  收藏  举报

导航