版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
OTSU算法,即最大类间方差,是由日本学者大津(Nobuyuki Otsu)于1979年提出的一种自适应阈值确定方法。算法假设一组数据能够根据阈值,被分为两部分,使得两类的区分度最大。两类之间的界限即为最佳分割阈值。大家有兴趣可以参考:Otsu, N. (1979)。
在数学上,数据D的阈值d可以表示为以下优化问题:
其中:
其中pi为数据中i的概率,L为数据D*的最大值。
代码实现如下:
int otsu(float *pix, int pixsize, float pixmin, float pixmax)
{
//pix 输入的数据
//pixsize 数据的长度
//pixmin 数据最小值
//pixmax 数据最大值
int pixsi = (int)pixmax - (int)pixmin+1;
int nThresh = (int)pixmin;
float *fStdHistogram = new float [pixsi]; // 图像直方图,pixsi个点
float *fGrayAccu = new float [pixsi];
float *fGrayAve = new float [pixsi];
float HistogramSum = 0.0;
float fAverage = 0;
float fTemp, fMax = 0;
memset(fStdHistogram, 0.0, sizeof(float) * pixsi);
memset(fGrayAccu, 0.0, sizeof(float) * pixsi);
memset(fGrayAve, 0.0, sizeof(float) * pixsi);
for (int i = 0; i < pixsize; ++i)
fStdHistogram[(int)pix[i] - (int)pixmin] += 1.0;
for (int i = 0; i < pixsi; ++i)
fStdHistogram[i] /= (pixsize * 1.0);
int minnew = 0, maxnew = pixsi;
for(int i = 0;i < pixsi; ++i)
{
for(int j = 0; j <= i; ++j)
{
fGrayAccu[i] += fStdHistogram[j];
fGrayAve[i] += j * fStdHistogram[j];
}
fAverage += i * fStdHistogram[i];
}
for(int i = 0; i < pixsi; ++i)
{
if (HistogramSum < 0.02) minnew = i;
if (HistogramSum >= 0.98)
{
maxnew = i;
break;
}
HistogramSum += fStdHistogram[i];
}
for(int i = minnew; i < maxnew; ++i)
{
fTemp = (fAverage * fGrayAccu[i] - fGrayAve[i]) * (fAverage * fGrayAccu[i] - fGrayAve[i]) / (fGrayAccu[i] * (1 - fGrayAccu[i]));
if(fTemp > fMax)
{
fMax = fTemp;
nThresh = i;
}
}
delete [] fStdHistogram;
delete [] fGrayAccu;
delete [] fGrayAve;
return 1 * (nThresh + (int)pixmin);
}
未完待续。