最大方差阈值分割--OTSU

最大方差阈值分割根据图像选择一个最优阈值T,这个T是如何得到的呢?
 
一副图像灰度值取 0~ 255 ,假设以 0 为阈值 >0为C1类  ;
                                                                                    
                                                                            其余为C0类 ; 
 
在假设以 1 为阈值 >1为C1类 其余为C0类  ...依次一直到255
 
那么 0~255哪个阈值才是这副图像最理想的阈值呢?这里就用到最大方差阈值分割
 
 
设图像像素总数为N ,灰度值范围为[0,L-1],灰度值i 的像素数位n(i) ,则灰度值i 的概率为
 
                         p(i) = n(i) / N ; 
 
把图像中的像素按灰度值用阈值T分成两类C0 C1 , C0 对应于灰度值在[0,T-1]之间的像素,C1对应于灰度值在
 
[T,L-1]之间的像素,则C0,C1的概率分别为
 
                        w0 = sum(  p(i)  )   = sum(  n(i)  )/N ;   i = [0,T-1] 
 
                        w1 = 1 - w0 
 
C0 和 C1 的均值分别为
 
                       u0 = sum( i * p(i)  ) / wo             i=[0,T-1]
     
                       u1 = sum( i * p(i) ) / w1               i=[T,L-1]
 
整个图像的灰度值均值为 u = w0 * u0 + w1 * u1
 
类间方差为 o^2 = w0 *( u0 - u) ^2 +w1*( u1 -u)^2 = wo * w1 * (u0 - u 1) ^2
 
 
分别取 T=0~255 计算类间方差,o^2最大值对应的T即为最优阈值。
 
OTSU 适用于直方图为双峰的图像,但是不均匀的照明等会导致不满足双峰条件,此时应采用动态阈值分割法。
 
 
/* 
    函数:outsThreshold 
    功能:最大方差阈值分割
    参数:pSrc 源图像
              pDest 目的图像
     限制:8位灰度图像
*/

int otusThreshold(IplImage *pSrc )
{
    //对各灰度值统计计数
    int nGrayHistogram[256];
    unsigned char nPixel = 0
    memset(nGrayHistogram,0,sizeof(nGrayHistogram));
    for (int i = 0 ; i < pSrc->height ; ++ i)
    {
        for (int j = 0 ; j < pSrc->width ; ++ j )
        {
            nPixel =(unsigned char ) *(pSrc->imageData + i * pSrc->widthStep + j );
            nGrayHistogram[nPixel]++;
        }
    }

    float u0,u1; // C0 C1均值
    float w0,w1; //C0 C1概率
    int nSum = pSrc->height * pSrc->width ; // 像素总数
    float fVaria = 0 ; //类间方差
    float fMaxVaria = 0 ; // 最大类间方差
    int fMaxVariT = 0 ; // 最大类间方差对应阈值
    for (int nT = 0 ; nT <256 ; ++nT)
    {
        //求C0 均值和概率
        for (int i = 0 ; i <=nT;++ i)
        {
            u0 += i * nGrayHistogram[i];
            w0 += nGrayHistogram[i];
        }
        u0 /= w0 ; 
        w0 /= nSum;

        //求C1均值和概率

        for (int i = nT +1 ; i <256 ; ++ i)
        {
            u1 += i * nGrayHistogram[i];
            w1 += nGrayHistogram[i];
        }
        u1 /= w1;
        w1 = 1 - w0;

        //求类间方差
        fVaria = w0 * w1 *( u0 - u1) * ( u0 - u1);
        if (fVaria >= fMaxVaria)
        {
            fMaxVaria = fVaria;
            fMaxVariT = nT;
        }
    }

    return fMaxVariT ; 
}
   
    





posted @ 2011-11-29 12:57  小马_xiaoLV2  阅读(1707)  评论(0编辑  收藏  举报