OSTU算法

  OSTU算法目的就是计算出一连通区域的阈值,然后对该区域二值化。

数学描述为:令连通区域S,其中象素灰度范围为[0,255],点(x,y)的灰度表示为I(x,y),灰度级x的点的概率为P(x);则OSTU就是求下式达到最大值的灰度级m

OSTU算法_第1张图片

 

使用OSTU对lena.bmp进行二值化,得到的结果如下:

OSTU算法_第2张图片

 

代码很简单,为了朋友更好的实践,如下所示:

//计算OSTU阈值 int CMyDIPView::OSTU(LPSTR lpDIBBits, int cxDIB, int cyDIB) { int i,j,nThresh=0; unsigned char *lpSrc; long lLineBytes = WIDTHBYTES(cxDIB * 8); // 计算图像每行的字节数 int nHistogram[256]; //规一化直方图 double fStdHistogram[256]; double fGrayAccu[256]; double fGrayAve[256]; double fAverage=0; double fTemp,fMax=0; //初始化 for(i=0;i<=255;i++) { nHistogram[i]=0; fStdHistogram[i]=0; fGrayAccu[i]=0; fGrayAve[i]=0; } //统计直方图 // 每行 for(i = 0; i < cyDIB; i++) { // 每列 for(j = 0; j < cxDIB; j++) { // 指向DIB第i行,第j个象素的指针 lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j; nHistogram[*lpSrc]++; } } for(i=0;i<=255;i++) { fStdHistogram[i]=nHistogram[i]/(double)(cyDIB*cxDIB); } for(i=0;i<=255;i++) { for(j=0;j<=i;j++) { fGrayAccu[i]+=fStdHistogram[j]; fGrayAve[i]+=j*fStdHistogram[j]; } fAverage+=i*fStdHistogram[i]; } //计算OSTU for(i=0;i<=255;i++) { fTemp=(fAverage*fGrayAccu[i]-fGrayAve[i])*(fAverage*fGrayAccu[i]-fGrayAve[i])/(fGrayAccu[i]*(1-fGrayAccu[i])); if(fTemp>fMax) { fMax=fTemp; nThresh=i; } } return nThresh; }

 

 

你可能感兴趣的:(图像处理)