OPenCV:采用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、用找到的阈值二值化图像

这个方法也可以用于图像分割。

  1. void ImageBinarization(IplImage *src)  
  2. {   /*对灰度图像二值化,自适应门限threshold*/  
  3.     int i,j,width,height,step,chanel,threshold;  
  4.     /*size是图像尺寸,svg是灰度直方图均值,va是方差*/  
  5.     float size,avg,va,maxVa,p,a,s;  
  6.     unsigned char *dataSrc;  
  7.     float histogram[256];  
  8.       
  9.     width = src->width;  
  10.     height = src->height;  
  11.     dataSrc = (unsigned char *)src->imageData;  
  12.     step = src->widthStep/sizeof(char);  
  13.     chanel = src->nChannels;  
  14.     /*计算直方图并归一化histogram*/  
  15.     for(i=0; i<256; i++)  
  16.         histogram[i] = 0;  
  17.     for(i=0; i<height; i++)  
  18.         for(j=0; j<width*chanel; j++)  
  19.         {  
  20.             histogram[dataSrc[i*step+j]-'0'+48]++;  
  21.         }  
  22.     size = width * height;  
  23.     for(i=0; i<256; i++)  
  24.         histogram[i] /=size;  
  25.     /*计算灰度直方图中值和方差*/  
  26.     avg = 0;  
  27.     for(i=0; i<256; i++)  
  28.         avg += i*histogram[i];  
  29.     va = 0;  
  30.     for(i=0; i<256; i++)  
  31.         va += fabs(i*i*histogram[i]-avg*avg);  
  32.     /*利用加权最大方差求门限*/  
  33.     threshold = 20;  
  34.     maxVa = 0;  
  35.     p = a = s = 0;  
  36.     for(i=0; i<256; i++)  
  37.     {  
  38.         p += histogram[i];  
  39.         a += i*histogram[i];  
  40.         s = (avg*p-a)*(avg*p-a)/p/(1-p);  
  41.         if(s > maxVa)  
  42.         {  
  43.             threshold = i;  
  44.             maxVa = s;  
  45.         }  
  46.     }  
  47.     /*二值化*/  
  48.     for(i=0; i<height; i++)  
  49.         for(j=0; j<width*chanel; j++)  
  50.         {  
  51.             if(dataSrc[i*step+j] > threshold)  
  52.                 dataSrc[i*step+j] = 255;  
  53.             else  
  54.                 dataSrc[i*step+j] = 0;  
  55.         }  
  56. }  

相关内容