Ostu算法

        图像二值化算法是图像处理的基础。一般来说,二值化算法可以分为两个类别:全局二值化和局部二值化。全局二值化是指通过某种算法找到一个全局的阈值T,对图像中坐标为(x,y)的像素值做如下处理:f(x,y)>T则f(x,y)=255,else f(x,y)=0
        Ostu就是这样一种全局二值化算法,又叫最大类间方差。因为该算法会遍历图像中任意一个像素值i,计算当其为阈值时,图像的前景和背景图像(并不一定是真正的前景和背景,只是我们把当前小于i的记做背景,大于i的记做前景)的方差值。当方差值达到最大时,我们认为此时的i是该图像的全局阈值。
说明: 
前景点数占图像比例:w0;平均灰度:u0
背景点数占图像比例:w1,平局灰度:u1
图像平均灰度:u=w0*u0 + w1*u1
前景和背景图像方差:

g=wo * (uo - u) * (uo - u) + w1 * (u1 - u) * (u1 - u)

  =wo * w1 * (uo - u1) * (uo - u1)  

int otsu(Mat dst){

	int i, j;
	int tmp;

	double u0, u1, w0, w1, u, uk;

	double cov;
	double maxcov = 0.0;
	int maxthread = 0;

	int hst[MAX_GRAY_VALUE] = { 0 };
	double pro_hst[MAX_GRAY_VALUE] = { 0.0 };

	int height = dst.cols;
	int width = dst.rows;

	//统计每个灰度的数量
	for (i = 0; i(i, j);
			hst[tmp]++;
		}
	}

	//计算每个灰度级占图像中的概率
	for (i = MIN_GRAY_VALUE; i maxcov)
		{
			maxcov = cov;
			maxthread = i;
		}
	}

	cout << maxthread << endl;
	return maxthread;
}


int main(){
	int width, height;
	int i, j;
	Mat obj = imread("E:/VS2013/face/xuelian/png/1.png");

	Mat dst;
	cvtColor(obj, dst, CV_RGB2GRAY);//灰度化
	
	height = dst.cols;//计算图像高度
	width = dst.rows;//计算图像宽度
	int thd = otsu(dst);

	imshow("origin img", dst);

	for (i = 0; i < width; i++)
	for (j = 0; j< height; j++)
	if (dst.at(i, j) > thd)
		dst.at(i, j) = MAX_GRAY_VALUE-1;
	else
		dst.at(i, j) = MIN_GRAY_VALUE;
	imshow("ostued", dst);
	waitKey(0);
	return 0;
}

           

你可能感兴趣的:(OpenCV,C++)