OpenCV实现OTSU算法(大津法)

int GetThresholdOTSU(Mat imgInput)
{
	int hist[256] = { 0 };
	double pro_hist[256] = { 0.0 };
	int row = imgInput.rows;
	int col = imgInput.cols;
	for (int i = 0; i < row; ++i) //统计每个灰度的数量
	{
		for (int j = 0; j < col; ++j)
		{
			int temp = imgInput.at<uchar>(i, j);
			hist[temp]++;
		}
	}
	for (int i = 0; i < 256; ++i)//计算每个灰度级占图像的概率
		pro_hist[i] = (double)hist[i] / (double)(row * col);
	double mG = 0.0;//平均灰度值
	for (int i = 0; i < 256; ++i)
		mG += i * pro_hist[i];
	double dbMaxVariance = 0.0;
	int nMaxthread = 0;
	for (int i = 0; i < 256; ++i)//统计前景和背景的平均灰度值,并计算类间方差
	{
		double m1 = 0.0; double m2 = 0.0; double mk = 0.0; double p1 = 0.0; double p2 = 0.0;
		for (int j = 0; j < i; ++j)
		{
			p1 += pro_hist[j];
			mk += j * pro_hist[j];
		}
		m1 = mk / p1;			//背景平均灰度
		p2 = 1 - p1;			//p1+p2=1;mG=p1*m1+p2*m2;
		m2 = (mG - mk) / p2;	//前景平均灰度
		double dbCurrVariance = p1 * p2 * (m1 - m2) * (m1 - m2);//计算类间方差,g=ω0(μ0-μ)^2+ω1(μ1-μ)^2
		if (dbCurrVariance > dbMaxVariance)
		{
			dbMaxVariance = dbCurrVariance;
			nMaxthread = i;
		}
	}
	return nMaxthread;
}

 

Guess you like

Origin blog.csdn.net/Stone_Wang_MZ/article/details/107470417