Otsu的C语言实现

翻译 2016年08月31日 15:34:31
//===============================================================================
//
//  函数名称: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;        
}

相关文章推荐

OTSU算法提取图像阈值的C语言实现

OTSU算法也称最大类间差法,有时也称之为大津算法,被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用。它是按图像的灰度特性,将图像分成背...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

C++实现otsu算法

类间方差最大化阈值分割算法 (Otsu)可以自动计算图像二值化时的阈值,otsu的中心思想是阈值T应使目标与背景两类的类间方差最大。具体原理如下:         otsu是按图像的灰度特性,将图像分...

自适应阈值分割—大津法(OTSU算法)C++实现

大津法是一种图像灰度自适应的阈值分割算法,是1979年由日本学者大津提出,并由他的名字命名的。大津法按照图像上灰度值的分布,将图像分成背景和前景两部分看待,前景就是我们要按照阈值分割出来的部分。背景和...
  • dcrmg
  • dcrmg
  • 2016年08月16日 21:46
  • 7416

OTSU算法提取图像阈值的C语言实现

OTSU算法也称最大类间差法,有时也称之为大津算法,被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用。它是按图像的灰度特性,将图像分成背...
  • zd0303
  • zd0303
  • 2011年10月29日 14:59
  • 1045

otsu阈值分割c#语言

  • 2009年04月20日 09:52
  • 3KB
  • 下载

Otsu算法的实现(opencv)

  • 2012年05月08日 15:25
  • 5.9MB
  • 下载

otsu算法---matlab实现,和一种改进算法

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 灰度图阈值分割提取前后背景 % otsu法和一种改进的方...

OTSU算法matlab实现

  • 2017年08月11日 17:26
  • 954B
  • 下载

阈值分割(OTSU)的C代码实现

  • 2016年05月23日 22:02
  • 819KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Otsu的C语言实现
举报原因:
原因补充:

(最多只允许输入30个字)