otsu 算法选择使类间方差最大的灰度值为阈值,具有很好的效果算
法具体描述见 otsu 论文,或冈萨雷斯有名的数字图像处理那本书这
里给出程序流程:
1 、计算直方图并归一化 histogram
2 、计算图像灰度均值 avgValue.
3 、计算直方图的零阶 w[i] 和一级矩 u[i]
4、计算并找到最大的类间方差〔between-class variance〕
variance[i]=(avgValue*w[i]-u[i])*(avgValue*w[i]-u[i])/(w[i]*(1-w[i]))
对应此最大方差的灰度值即为要找的阈值
5、用找到的阈值二值化图像
我在代码中做了一些优化,所以算法描述的某些地方跟程序并不全都
otsu 代码,先找阈值,继而二值化
// implementation of otsu algorithm
// author: onezeros(@yahoo.cn)
// reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB
void cvThresholdOtsu(IplImage* src, IplImage* dst)
{
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;