opencv实现c++的otsu自适应阈值分割的算法描述

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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(@)

// 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

{

unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;

for(int j=0; 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];

u+=i*histogram[i];

float t=avgValue*w-u;

float variance=t*t/(w*(1-w));

if(variance>maxVariance)

{

maxVariance=variance;

threshold=i;

}

}

cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY);

}

更多情况下我们并不需要对每一帧都是用otsu寻找阈值,于是可以先找到阈值,然后用找到的阈值处理后面的图像。下面这个函数重载了上面的,返回值就是阈值。只做了一点改变

// implementation of otsu algorithm

// author: onezeros(@)

// reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB

int cvThresholdOtsu(IplImage* src)

{

int height=src->height;

int width=src->width;

//histogram

float histogram[256]= {0};

for(int i=0; i

{

unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;

for(int j=0; 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];

u+=i*histogram[i];

float t=avgValue*w-u;

float variance=t*t/(w*(1-w));

if(variance>maxVariance)

{

maxVariance=variance;

相关文档
最新文档