图像二值化方法--OTSU(最大类间方差法)

前面学习了直方图双峰法:图像二值化方法中的阈值法

最大类间方差法(OTSU)是找到自适应阈值的常用方法。原理参考了冈萨雷斯的《数字图像处理》。

以下是自己写的函数:

//----获取灰度图in的OTSU阈值--
int Segment::otsuMat(Mat in)
{
	int i,j;
	int temp;
	//第一类均值,第二类均值,全局均值,mk=p1*m1, 第一类概率,第二类概率
	double m1,m2,mG,mk,p1,p2;

	int hist[256] = {0};
	double pro_hist[256] = {0.0};

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

	int row = in.rows;
	int col = in.cols;

	//统计每个灰度的数量
	for(i=0; i<row; ++i) {
		for(j=0; j<col; ++j) {
			temp = in.at<uchar>(i,j);
			hist[temp]++;
		}
	}

	//计算每个灰度级占图像的概率
	for(i=0; i<256; ++i)
		pro_hist[i] = (double)hist[i]/(double)(row*col);

	//计算平均灰度值
	mG = 0.0;
	for(i=0; i<256; ++i)
		mG += i * pro_hist[i];

	//统计前景和背景的平均灰度值,并计算类间方差
	for(i=0; i<256; ++i)
	{
		m1=0.0; m2=0.0; mk=0.0; p1=0.0; p2=0.0;
		for(j=0; j<i; ++j) {
			p1 += pro_hist[j];
			mk += j*pro_hist[j];
		}

		m1 = mk/p1;  //mk=p1*m1,是一个中间值

		p2 = 1 - p1;  //p1+p2=1;
		m2 = (mG - mk)/p2;  //mG=p1*m1+p2*m2;

		//计算类间方差
		cov = p1*p2*(m1-m2)*(m1-m2);
		if(cov>maxcov) {
			maxcov = cov;
			maxthread = i;
		}
	}
	//cout<<maxthread<<endl;
	return maxthread;

}
每次需要的时候就直接复制粘贴,效果常常很满意,就感觉要二值化OTSU法总可以用上,但是今天发现不好用了。我需要把一组图片分离出目标和背景,选取了Lab空间中的L通道,直接使用OTSU法。本来这一组图背景很相似,但是结果发现分割后有一些图片错误太明显。查看了阈值,发现相差蛮多的。例如下面的四张图。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值