1、描述:
主要是思想是取某个阈值,使得前景和背景两类的类间方差最大,matlab中的graythresh即是以该算法为原理执行的。
该算法是日本人Otsu提出的一种动态阈值分割算法。它的主要思想是按照灰度特性将图像划分为背景和目标2部分,划分依据为选取门限值,使得背景和目标之间的方差最大。(背景和目标之间的类间方差越大,说明这两部分的差别越大,当部分目标被错划分为背景或部分背景错划分为目标都会导致这两部分差别变小。因此,使用类间方差最大的分割意味着错分概率最小。)这是该方法的主要思路。其主要的实现原理为如下:
1)建立图像灰度直方图(共有L个灰度级,每个出现概率为p)
2)计算背景和目标的出现概率,计算方法如下:
上式中假设t为所选定的阈值,A代表背景(灰度级为0~N),根据直方图中的元素可知,Pa为背景出现的概率,同理B为目标,Pb为目标出现的概率。
3)计算A和B两个区域的类间方差如下:
第一个表达式分别计算A和B区域的平均灰度值;
第二个表达式计算灰度图像全局的灰度平均值;
第三个表达式计算A、B两个区域的类间方差。
参考代码:
//计算每个直方图占总数的概率
double Prob_gray[256];
for(int a=0;a<256;a++)
{
Prob_gray[a]=(double)graycolor[a]/(w*h);
//cout<<a<<":"<<Prob_gray[a]<<endl;
}
//定义两个数组存储计算的概率,假设t为阙值,计算每个t的前后像素的概率
double Pa=0,Pa1=0,Pb=0,Pb1=0; //存储概率
double Wa[256],Wb[256],Wo[256],Wz[256],Wz1[256];//存储概率的数组,Wa为A区域的平均灰度值,Wb为B区域的平均灰度值,
Wo为图像全局的灰度平均值,Wz,Wz1 A、B两个区域的类间方差
for (int t=0;t<256;t++)
{
Wa[t]=0;
Wb[t]=0;
Wo[t]=0;
Wz[t]=0;
Wz1[t]=0;
}
for (int t=0;t<256;t++)
{
Pa=0;Pb=0;Pa1=0;Pb1=0;
for(int p=0;p<t+1;p++)
{
Pa=Prob_gray[p]*p+Pa;
Pa1=Prob_gray[p]+Pa1;
}
//cout<<Pa1<<"\t"<<Pa<<"\t";
Wa[t]=Pa/Pa1; //每个t的前几项的概率方差
//cout<<Wa[t]<<endl;
for(int q=t+1;q<256;q++)
{
Pb=Prob_gray[q]*q+Pb;
Pb1=Prob_gray[q]+Pb1;
}
Wb[t]=Pb/Pb1; //每个t的后几项的概率方差
Wo[t]=Wa[t]*Pa1+Wb[t]*Pb1;
Wz[t]=Pa1*(Wa[t]-Wo[t])*(Wa[t]-Wo[t])+Pb1*(Wb[t]-Wo[t])*(Wb[t]-Wo[t]);
cout<<Wz[t]<<endl;
}
double max=0;
for (int t=0;t<256;t++)
{
Wz1[t]=Wz[t];
if(Wz1[t]>max) max=Wz1[t];
}
cout<<"max"<<max<<endl; //输出的为最大的方差
for (int t=0;t<256;t++)
{
if(Wz[t]>=max) cout<<t; //输出的为最大的方差的灰度值位置,即阙值位置
}