OTSU最大类间方差法(求自适应阈值)

本文详细介绍了OTSU最大类间方差法的基本原理及其应用。OTSU算法是一种动态二值化方法,用于自动确定图像的最佳阈值,实现前景与背景的有效分离。文章提供了算法的性能特点、适用条件及其实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



OTSU,最大类间方差法 。是一种动态二值化方法。其基本思想是:假设一个阈值,将灰度图像的灰度统图分成两部分(前景部分和背景部分,也成为亮区和暗区),在这两类的类间方差最大的时候,得到的阈值是最优的二值化阈值。

 

性能:

1)类间方差法对噪音十分敏感,在处理之前应对图片进行去噪处理。

2)当目标与背景的大小比例悬殊的时候,类间方差函数可能呈现双峰或者多峰,这个时候 效果不好。慎用!

 

处理步骤:

1.对图片进行灰度化处理,并且计算其灰度值统计表N(假设图像大小为P×Q);

2.计算前景像素点数(灰度大于假设阈值T)占整个图像的比例,记做W0

  N(i)表示统计图第i列的数值;

 


 

 计算前景像素点的平均灰度值U0

 

3.同理求出背景的W1和U1(累加的时候从T加到灰度的最大值)

4.求整个图像的平均灰度值:U=W0×U0 + W1×U1 

5.从L个灰度级遍历T,使得T为某个值的时候,前景和背景的方差最大, 则 这个 T 值便是我们要求得的阈值。其中,方差的计算公式如下:

    G=W0 × (U0 - U) × (U0 - U) + w1 × (U1 - U) × (U1 - U)

 此公式计算量较大,可以采用: 

    G= W0 ×  W1 ×  (U0 - U1) ×  (Uo - U1)

 

 上代码:

//设t为设定的阈值。
//wo: 分开后 前景像素点数占图像的比例
//uo: 分开后 前景像素点的平均灰度
//w1:分开后 被景像素点数占图像的比例
//u1: 分开后 被景像素点的平均灰度
//u=w0*u0 + w1*u1 :图像总平均灰度
//
//从L个灰度级遍历t,使得t为某个值的时候,前景和背景的方差最大, 则 这个 t 值便是我们要求得的阈值。
//其中,方差的计算公式如下:
//g=wo * (uo - u) * (uo - u) + w1 * (u1 - u) * (u1 - u)
//[此公式计算量较大,可以采用:g = wo * w1 * (uo - u1) * (uo - u1)
int OTSU_THRESHVALU(IplImage *image)
{
	//函数处理的图像需要是灰度图(通道数为1)
	//灰度图像
	IplImage *gray_image = cvCreateImage(cvGetSize(image),image->depth,1);
	//判断图像是否为灰度图
	if (image->nChannels == 3)
	{
		cvCvtColor(image, gray_image, CV_RGB2GRAY);
	}
	else
	{
		cvCopy(image, gray_image);
	}

	//直方图均衡化
	cvEqualizeHist(gray_image, gray_image);
	//存放灰度统计数组
	int bin[255];
	//初始化
	memset(bin,0,sizeof(bin));
	CvScalar scalar_Valu;
	//灰度跨度的最大值和最小值
	int max_num = 0;
	int min_num = 255;
	//计算图像的灰度值直方图
	for (int i = 0; i < gray_image->height; i++)
	{
		for (int j = 0; j < gray_image->width; j++)
		{
			scalar_Valu = cvGet2D(gray_image, i, j);
			int num = scalar_Valu.val[0];
			bin[num]++;
			//计算图像的灰度跨度
			if (num > max_num) max_num = num;
			if (num < min_num) min_num = num;
		}
	}
	//最大的G;最合适的阈值
	double max_G = 0.0;
	int thresh_num = 0;
	//计算w1,u1,w2,u2
	for (int i = min_num; i <= max_num; i++)
	{
		//灰度值大于I的
		long sum_up_bin = 0;
		long sum_up_num = 0;
		for (int j = i; j <= max_num; j++)
		{
			sum_up_bin += bin[j];
			sum_up_num += (j * bin[j] * 1.0);
		}
		double u1 = sum_up_num / (sum_up_bin * 1.0);
		double w1 = (sum_up_bin * 1.0) / (gray_image->width * gray_image->height * 1.0);
		//计算灰度小于I的部分
		long sum_down_bin = 0;
		long sum_down_num = 0;
		for (int j = min_num; j < i; j++)
		{
			sum_down_bin += bin[j];
			sum_down_num += (j * bin[j] * 1.0);
		}
		double u2 = sum_down_num / (sum_down_bin * 1.0);
		double w2 = (sum_down_bin * 1.0) / (gray_image->width * gray_image->height);
		//计算G值
		double u = (w1 * u1 + w2 * u2);
		double G = w1 * (u1 - u) * (u1 - u) + w2 * (u2 - u) * (u2 - u);
		//判断G值的大小,并计算出最佳阈值
		if (G > max_G)
		{
			max_G = G;
			thresh_num = i;
		}
	}
	return thresh_num;
}


 

   

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值