openCV2——ostu

ostu:大津阈值法,通过选择某个阈值,来使亮度不同的背景和前景尽可能分开来。

原理及步骤:

0.建立直方图数组count[256],存放着0~255亮度值各自的像素量;

1.选择某个阈值k,将一幅像素量total=rows*cols的图像分为亮部和暗部
,亮部像素量W,暗部像素量B,则亮部比例w1=W / total,暗部比例w2=B / total;

2.整体图像平均灰度u0=(count[0,255].*[0,255])/total
,亮部平均灰度u1=(count[0,k-1].*[0,k-1]) / sum(count[0,k-1])
,暗部平均灰度u2=(count[k,255].*[k,255]) / sum(count[k,255])
,且满足u0=u1*w1+u2*w2(式0);

3.方差值=w1(u1-u0)^2+w2*(u2-u0)^2
,根据式0,可整理为:
方差值=w1*w2*(u1-u2)^2;

4.循环1-3步,直到方差值最大时,即为所求k值

c++函数为:

unsigned char myOstu(const cv::Mat &gray)
{
int row=gray.rows, col=gray.cols;
unsigned long long size=row*col;//total pixs
int count[256];// histogram space 
for (int ind=0;ind<256;ind++)
{
	count[ind]=0;
}

for(int i=0;i(i,j)]++;
	}

double w1,w2;//black background//white frontground
double blackNum, whiteNum;
double maxVar=0, tmp;
double meanBlackLevel=0.0, meanWhiteLevel=0.0;
unsigned char ostu;
for (int k=0;k<256;k++)
{
	//compute the w1 and w2
	blackNum=0;		whiteNum=0;
	for (int i=0;imaxVar) 
	{
		maxVar=tmp;
		ostu=k;
	}
}
return ostu;

}

你可能感兴趣的:(openCV2——ostu)