图像处理算法2——Otsu最佳阈值分割法

  • Post author:
  • Post category:其他


Otsu法是1979年由日本大津提出的。该方法在

类间方差最大

的情况下是最佳的,即统计鉴别分析中所用的度量。Otsu方法有一个重要的特性,就是它完全以在一幅图像的直方图上执行计算为基础,而直方图是很容易得到的一维阵列。

具体的公式推理及公式细节就不说了,详见 Conzalez 那本书,我是第三版的,在

P.479——P.482

上面。

给出具体步骤如下:

1、计算输入图像的直方图,并归一化。

2、计算累积均值mu,以及全局灰度均值。

3、计算被分到类1的概率q1,和被分到类2的概率q2。

4、用公式计算类间方差,sigma = q1*q2*(mu1 – mu2)*(mu1 – mu2)

5、循环寻找类间方差最大值,并记下此时的阈值,即为最佳阈值。

6、利用最佳阈值进行图像阈值化。

关于otsu部分的程序代码如下:

double getThreshVal_Otsu_8u( const Mat& _src )
{
	Size size = _src.size();
	const int N = 256;
	int i, j, h[N] = {0};
	unsigned char* src;
	//直方图统计
	for( i = 0; i < size.height; i++ )
	{
		src = _src.data + _src.step*i;
		j = 0;
		for(j = 0; j < size.width; j++ )
			h[src[j]]++;
	}
	//像素平均值
	double mu = 0, scale = 1./(size.width*size.height);
	for( i = 0; i < N; i++ )
	{
		mu += i*(double)h[i];//累加均值
	}
	mu *= scale;//平均

	double mu1 = 0, q1 = 0;//q1 ,q2 为类1和类2的概率累积和,mu1=mg*q1
	double p_i, q2, mu2, sigma;
	double max_sigma = 0, max_val = 0;
	//循环求取最大阈值
	for( i = 0; i < N; i++ )
	{
		p_i = h[i]*scale;//直方图归一化
		mu1 *= q1;
		q1 += p_i;
		q2 = 1. - q1;
		mu1 = (mu1 + i*p_i)/q1;
		mu2 = (mu - q1*mu1)/q2;
		sigma = q1*q2*(mu1 - mu2)*(mu1 - mu2);//类间方差
		if( sigma > max_sigma )
		{
			max_sigma = sigma;
			max_val = i;//记下使类间方差最大的阈值
		}
	}
	return max_val;//返回阈值
}

注意,上面这部分传递的图像是

Mat 类型

的,和 Iplimage 类型在图像参数部分写法上有一点区别,注意区分开来

显示结果如下:




版权声明:本文为xiaqunfeng123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。