基于YCrCb空间的Otsu自适应阈值算法

Otsu(最大类间差)算法思想:将图像分别用每个像素p点分割为前景区域背景区,计算在被像素点p分割的前景区域背景区的像素个数、平均像素,及像素比例,最后计算方差值,则取最大方差时的像素点p则为最佳阈值。

void skin_ThreshOtsu(Mat * src, Mat * mask)
{
	Mat srcImg;
	src->copyTo (srcImg);
	Mat YCrCb_Img ;
	cvtColor (srcImg, YCrCb_Img,CV_RGB2YCrCb );//将颜色空间从RGB转换为YCrCb
	Mat Cr_Img;
	vector <Mat> channels;
	split(YCrCb_Img,channels);
	Cr_Img = channels [2];
	//threshold (Cr_Img ,Cr_Img, 0, 255, CV_THRESH_OTSU  );//已实现的Otsu阈值分割
	Mat otsu_Img;
	Cr_Img.copyTo(otsu_Img);
	//计算直方图
	float histogram[256] = {0};//因计算灰度直方图,灰度范围在0~255
	float pixel_sum = 0;//像素和
	for (int i = 0; i< otsu_Img.rows; i++)
	{
		uchar * p = otsu_Img.ptr<uchar>(i);//获取第i行首行
		for (int j = 0; j < otsu_Img.cols; j++)
		{
			histogram[(int)*p++] ++;  // 在第i行的第p列时histogram的第p列加1;
		}
			
	}
	long int  sum = otsu_Img.size().height * otsu_Img.size().width;//总像素数
	//迭代计算
	int thresh = 0;//最佳阈值;
	double maxvariance = 0;//最大类间方差
	for (int i = 0; i < 256; i++)//i级灰度,遍历没一级像素i
	{
		long sum0 = 0, sum1 = 0;//存储前景灰度总和及背景灰度总和
		double cnt0 = 0, cnt1 = 0;//存储前景灰度总个数及背景灰度总个数
		double w0 = 0, w1 = 0;//存储前景灰度个数及背景灰度个数占总灰度个数的比值
		double u0 = 0, u1 = 0;//存储前景及背景的平均灰度,灰度除以灰度个数
		double variance = 0; // 最大类间方差
		for (int j = 0; j < i; j++)//计算前景灰度, 0<j<i表示前景灰度,j> i 表示背景灰度
		{
			sum0 += j * histogram [j];
			cnt0 += histogram [j];
		}
		w0 = cnt0 / sum;
		u0 = sum0 / cnt0;
		for (int j = i; j < 256; j++)//计算背景灰度
		{
			sum1 += j * histogram [j];
			cnt1 += histogram [j];
		}
		w1 = 1-w0;
		u1 = sum1 / cnt1;

		variance = w0 * w1 * (u0 - u1) * (u0 - u1);
		if (variance > maxvariance )
		{
			maxvariance = variance;
			thresh = i;
		}
	}
	threshold (otsu_Img, *mask, thresh, 255, CV_THRESH_BINARY );

	imshow("cr_img", *mask );
	//*mask = ~ Cr_Img ;

}

参考文献
https://blog.csdn.net/ap1005834/article/details/51452516
https://blog.csdn.net/onezeros/article/details/6136770
https://blog.csdn.net/qq_20823641/article/details/51480651

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值