Ostu算法

7 篇文章 0 订阅
        图像二值化算法是图像处理的基础。一般来说,二值化算法可以分为两个类别:全局二值化和局部二值化。全局二值化是指通过某种算法找到一个全局的阈值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<width; i++){
		for (j = 0; j<height; j++){
			tmp = dst.at<uchar>(i, j);
			hst[tmp]++;
		}
	}

	//计算每个灰度级占图像中的概率
	for (i = MIN_GRAY_VALUE; i<MAX_GRAY_VALUE; i++)
		pro_hst[i] = (double)hst[i] / (double)(width*height);

	//计算全局平均灰度值
	u = 0.0;
	for (i = MIN_GRAY_VALUE; i<MAX_GRAY_VALUE; i++)
		u += i*pro_hst[i];

	//double det = 0.0;
	//for (i = MIN_GRAY_VALUE; i< MAX_GRAY_VALUE; i++)
		//det += (i - u)*(i - u)*pro_hst[i];

	//统计前景和背景的平均灰度值,并计算类间方差

	for (i = MIN_GRAY_VALUE; i<MAX_GRAY_VALUE; i++){

		w0 = 0.0; w1 = 0.0; u0 = 0.0; u1 = 0.0; uk = 0.0;

		for (j = MIN_GRAY_VALUE; j < i; j++){

			uk += j*pro_hst[j];
			w0 += pro_hst[j];//前景占图像画幅比例

		}
		u0 = uk / w0;//前景平均灰度
		w1 = 1 - w0;//背景占图像画幅比例
		u1 = (u - uk) / (1 - w0);//背景平均灰度

		//计算类间方差
		cov = w0*w1*(u1 - u0)*(u1 - u0);

		if (cov > 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<uchar>(i, j) > thd)
		dst.at<uchar>(i, j) = MAX_GRAY_VALUE-1;
	else
		dst.at<uchar>(i, j) = MIN_GRAY_VALUE;
	imshow("ostued", dst);
	waitKey(0);
	return 0;
}

           

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值