OPenCV:采用otsu自适应门限的图像二值化方法
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、用找到的阈值二值化图像
这个方法也可以用于图像分割。
- void ImageBinarization(IplImage *src)
- { /*对灰度图像二值化,自适应门限threshold*/
- int i,j,width,height,step,chanel,threshold;
- /*size是图像尺寸,svg是灰度直方图均值,va是方差*/
- float size,avg,va,maxVa,p,a,s;
- unsigned char *dataSrc;
- float histogram[256];
- width = src->width;
- height = src->height;
- dataSrc = (unsigned char *)src->imageData;
- step = src->widthStep/sizeof(char);
- chanel = src->nChannels;
- /*计算直方图并归一化histogram*/
- for(i=0; i<256; i++)
- histogram[i] = 0;
- for(i=0; i<height; i++)
- for(j=0; j<width*chanel; j++)
- {
- histogram[dataSrc[i*step+j]-'0'+48]++;
- }
- size = width * height;
- for(i=0; i<256; i++)
- histogram[i] /=size;
- /*计算灰度直方图中值和方差*/
- avg = 0;
- for(i=0; i<256; i++)
- avg += i*histogram[i];
- va = 0;
- for(i=0; i<256; i++)
- va += fabs(i*i*histogram[i]-avg*avg);
- /*利用加权最大方差求门限*/
- threshold = 20;
- maxVa = 0;
- p = a = s = 0;
- for(i=0; i<256; i++)
- {
- p += histogram[i];
- a += i*histogram[i];
- s = (avg*p-a)*(avg*p-a)/p/(1-p);
- if(s > maxVa)
- {
- threshold = i;
- maxVa = s;
- }
- }
- /*二值化*/
- for(i=0; i<height; i++)
- for(j=0; j<width*chanel; j++)
- {
- if(dataSrc[i*step+j] > threshold)
- dataSrc[i*step+j] = 255;
- else
- dataSrc[i*step+j] = 0;
- }
- }
评论暂时关闭