c++实现基于直方图的图像全局二值化算法原理、实现--OSTU大律法,找最佳阈值

1、描述:

   主要是思想是取某个阈值,使得前景和背景两类的类间方差最大,matlab中的graythresh即是以该算法为原理执行的。

该算法是日本人Otsu提出的一种动态阈值分割算法。它的主要思想是按照灰度特性将图像划分为背景和目标2部分,划分依据为选取门限值,使得背景和目标之间的方差最大。(背景和目标之间的类间方差越大,说明这两部分的差别越大,当部分目标被错划分为背景或部分背景错划分为目标都会导致这两部分差别变小。因此,使用类间方差最大的分割意味着错分概率最小。)这是该方法的主要思路。其主要的实现原理为如下:

      1)建立图像灰度直方图(共有L个灰度级,每个出现概率为p)


      2)计算背景和目标的出现概率,计算方法如下:


      上式中假设t为所选定的阈值,A代表背景(灰度级为0~N),根据直方图中的元素可知,Pa为背景出现的概率,同理B为目标,Pb为目标出现的概率。

      3)计算A和B两个区域的类间方差如下:


       第一个表达式分别计算A和B区域的平均灰度值;

      第二个表达式计算灰度图像全局的灰度平均值;

      第三个表达式计算A、B两个区域的类间方差。

参考代码:

//计算每个直方图占总数的概率
	double Prob_gray[256];
	for(int a=0;a<256;a++)
	{
		Prob_gray[a]=(double)graycolor[a]/(w*h);
		//cout<<a<<":"<<Prob_gray[a]<<endl;
	}
//定义两个数组存储计算的概率,假设t为阙值,计算每个t的前后像素的概率
	double Pa=0,Pa1=0,Pb=0,Pb1=0;      //存储概率
	double Wa[256],Wb[256],Wo[256],Wz[256],Wz1[256];//存储概率的数组,Wa为A区域的平均灰度值,Wb为B区域的平均灰度值,
Wo为图像全局的灰度平均值,Wz,Wz1 A、B两个区域的类间方差
	for (int t=0;t<256;t++)
	{
		Wa[t]=0;
		Wb[t]=0;
		Wo[t]=0;
		Wz[t]=0;
		Wz1[t]=0;
	}
	for (int t=0;t<256;t++)
	{
		Pa=0;Pb=0;Pa1=0;Pb1=0;
		for(int p=0;p<t+1;p++)
		{
			Pa=Prob_gray[p]*p+Pa;
			Pa1=Prob_gray[p]+Pa1;
		}
		//cout<<Pa1<<"\t"<<Pa<<"\t";
		Wa[t]=Pa/Pa1;        //每个t的前几项的概率方差
		//cout<<Wa[t]<<endl;
		for(int q=t+1;q<256;q++)
		{
			Pb=Prob_gray[q]*q+Pb;
			Pb1=Prob_gray[q]+Pb1;
		}
		Wb[t]=Pb/Pb1;        //每个t的后几项的概率方差
		Wo[t]=Wa[t]*Pa1+Wb[t]*Pb1;
	    Wz[t]=Pa1*(Wa[t]-Wo[t])*(Wa[t]-Wo[t])+Pb1*(Wb[t]-Wo[t])*(Wb[t]-Wo[t]);
		cout<<Wz[t]<<endl;
	} 
	double max=0;
	for (int t=0;t<256;t++)
	{
		Wz1[t]=Wz[t];
		if(Wz1[t]>max) max=Wz1[t];
	}
	cout<<"max"<<max<<endl;       //输出的为最大的方差
	for (int t=0;t<256;t++)
	{
		if(Wz[t]>=max) cout<<t;   //输出的为最大的方差的灰度值位置,即阙值位置
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值