关闭

Otsu的C语言实现

300人阅读 评论(0) 收藏 举报
分类:
//===============================================================================
//
//  函数名称:OTSU_threshold
//  功能说明:经典大津算法 动态阈值
//  修改时间:2016-8-31
//  备    注:
//      Otsu实现思路
//  1.计算0~255各灰阶对应的像素个数,保存至一个数组中,该数组下标是灰度值,保存内容是当前灰度值对应像素数
//  2.计算背景图像的平均灰度、背景图像像素数所占比例
//  3.计算前景图像的平均灰度、前景图像像素数所占比例
//  4.遍历0~255各灰阶,计算并寻找类间方差极大值
//===============================================================================
#define Gourd 256
uint8 OTSU_threshold(uint8 *pic,uint16 num)
{
   uint16 i=0;
   uint16 Histogram[Gourd];//直方图histogram
   for (i=0;i<Gourd;i++)
       Histogram[i]=0;//数组清零

   for (i=0;i<num;i++)
   {
       Histogram[(int)pic[i]*Gourd/256]++;//遍历每个像素,计算每个灰度级的像素个数和。
   }

  float pt[Gourd],w[Gourd],u[Gourd],o[Gourd],Ut;

  pt[0]=(float)Histogram[0]/num;
  w[0]=pt[0];
  u[0]=w[0];

  for(i=1;i<Gourd;i++)
  {
    pt[i]=(float)Histogram[i]/num; //灰度级为i的像素个数占总像素的比例
    w[i]=w[i-1]+pt[i];//进行pt[i]的累加。对图像像素数所占比例进行累加
    u[i]=u[i-1]+i*pt[i];//进行i*pt[i]的累加,从而计算出平均灰度(每个灰度级*每个灰度级所占的比例) 
  };
  Ut=u[Gourd-1];//整幅图像平均灰度

  for(i=0;i<Gourd;i++)
  {
    o[i]=(1-pt[i])*(u[i]*u[i]/w[i]+(u[i]-Ut)*(u[i]-Ut)/(1-w[i]));//方差
  };

  int maxi=0;
  float maxo=0;

  for(i=0;i<Gourd;i++)
  {
    if(o[i]!=0x7FC0000)
    if(o[i]>maxo){maxo=o[i];maxi=i;}//遍历0~255各灰阶,计算并寻找类间方差极大值,当找到时,i为对应类间方差的灰度值

  }
  return maxi*256/Gourd;
}
//Otsu的C++实现
//转自

> http://www.cnblogs.com/gzy-zju-edu/articles/4202252.html

int Otsu(IplImage* src)        
{        
    int height=src->height;        
    int width=src->width;            

    //histogram        
    float histogram[256] = {0};        
    for(int i=0; i < height; i++)      
    {        
        unsigned char* p=(unsigned char*)src->imageData + src->widthStep * i;        
        for(int j = 0; j < width; j++)       
        {        
            histogram[*p++]++;        
        }        
    }        
    //normalize histogram        
    int size = height * width;        
    for(int i = 0; i < 256; i++)      
    {        
        histogram[i] = histogram[i] / size;        
    }        

    //average pixel value        
    float avgValue=0;        
    for(int i=0; i < 256; i++)      
    {        
        avgValue += i * histogram[i];  //整幅图像的平均灰度      
    }         

    int threshold;          
    float maxVariance=0;        
    float w = 0, u = 0;        
    for(int i = 0; i < 256; i++)       
    {        
        w += histogram[i];  //假设当前灰度i为阈值, 0~i 灰度的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例      
        u += i * histogram[i];  // 灰度i 之前的像素(0~i)的平均灰度值: 前景像素的平均灰度值      

        float t = avgValue * w - u;        
        float variance = t * t / (w * (1 - w) );        
        if(variance > maxVariance)       
        {        
            maxVariance = variance;        
            threshold = i;        
        }        
    }        

    return threshold;        
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:4172次
    • 积分:291
    • 等级:
    • 排名:千里之外
    • 原创:25篇
    • 转载:0篇
    • 译文:1篇
    • 评论:5条
    最新评论