• 最大方差阈值分割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 ; 
    }
       
        





  • 相关阅读:
    @Profile使用及SpringBoot获取profile值
    浅谈maven中的scope,systempath
    Maven Filter与Profile隔离生产环境与开发环境
    spring的@Value注解使用
    maven项目引入spring boot依赖之后filter不生效的问题
    SpringBoot整合Servlet的两种方式
    程序员,30岁,“理所应当”就该中年危机了吗?
    Spring Boot 2 Webflux的全局异常处理
    正经学C#_表达式与其运算符[赋值运算符]:《c#入门经典》
    正经学C#_表达式与其运算符[算术运算符]:《c#入门经典》
  • 原文地址:https://www.cnblogs.com/xiaomaLV2/p/2267468.html
Copyright © 2020-2023  润新知