大津阈值法原理_ostu阈值分割

大津阈值法原理_ostu阈值分割具体的公式推导参见冈萨雷斯**《数字图像处理》**Otsu方法又称最大类间方差法,通过把像素分配像素分为两类或多类,计算类间方差,当方差达到最大值时,类分割线(即灰度值)就作为图像分割阈值。Otsu还有一个重要的性质,即它完全基于对图像直方图进行计算,这也使他成为最常用的阈值处理算法之一。算法步骤如下:…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

具体的公式推导参见冈萨雷斯 《数字图像处理》

Otsu方法又称最大类间方差法,通过把像素分配为两类或多类,计算类间方差,当方差达到最大值时,类分割线(即灰度值)就作为图像分割阈值。Otsu还有一个重要的性质,即它完全基于对图像直方图进行计算,这也使他成为最常用的阈值处理算法之一。

算法步骤如下:
在这里插入图片描述
Otsu只有在直方图呈现双峰的时候才会有一个很好的效果,在直方图单峰或多峰的情况下效果不是很好,那就需要通过实际情况来选取其他的方法来得到预期的分割效果。

代码如下;

//返回阈值的大津阈值法
double Otsu_threshold(const cv::Mat& InputImage)
{ 
   	
	cv::Mat SrcImage = InputImage.clone();
	CV_Assert(SrcImage.type() == CV_8UC1);

	int rows = SrcImage.rows;
	int cols = SrcImage.cols;

	const int L = 256;
	int N = rows * cols;					//灰度图大小(元素个数)
	int n_i[L] = { 
    0 };						//灰度直方图
	
	for (int i = 0; i < rows; ++i)
	{ 
   
		uchar* p = SrcImage.ptr<uchar>(i);
		for (int j = 0; j < cols; ++j)
			n_i[p[j]]++;
	}

	double pn_i[L];							//概率灰度直方图
	for (int i = 0; i < L; ++i)
	{ 
   
		pn_i[i] = (double)n_i[i] / N;
	}

	//全局均值和全局方差
	cv::Mat mat_mean, mat_stddev;
	double gray_mean, gray_sigma;

	cv::meanStdDev(SrcImage, mat_mean, mat_stddev);
	gray_mean = mat_mean.at<double>(0, 0);			//m_G
	//全局方差是用来计算类的可分离测度
	gray_sigma = mat_stddev.at<double>(0, 0) * mat_stddev.at<double>(0, 0);

	//遍历所有灰度级,计算类间方差
	std::vector<double>sigma_ks(L);
	for (int k = 0; k < L; ++k)
	{ 
   
		double p1 = 0.0;				//p1类发生概率
		double m_k = 0.0;				//高达k阶累计平均灰度

		for (int i = 0; i <= k; ++i)
		{ 
   
			p1 += pn_i[i];
			m_k += i * pn_i[i];
		}

		if (p1 == 0.0 || (1 - p1) == 0.0)					//分母不能为0
			sigma_ks[k] = 0.0;
		else
			sigma_ks[k] = (gray_mean * p1 - m_k) * (gray_mean * p1 - m_k) / (p1 * (1 - p1));
	}

	double max_Sigma_k = 0.0;
	std::vector<int>maxval_Ts;
	double Threshold_T = 0;									//最终输出的阈值T
	//找类间方差最大值
	for (int i = 0; i < sigma_ks.size(); ++i)
	{ 
   
		if (sigma_ks[i] > max_Sigma_k)
			max_Sigma_k = sigma_ks[i];
	}
	//找极大值对应的所有灰度值
	for (int i = 0; i < sigma_ks.size(); ++i)
	{ 
   
		if (abs(max_Sigma_k - sigma_ks[i]) < 1e-8)
			maxval_Ts.push_back(i);
	}
	//如果极大值点不唯一,那么取对应各个极大值的各个k的平均值来得到最终阈值threshold_T
	for (int i = 0; i < maxval_Ts.size(); ++i)
		Threshold_T += maxval_Ts[i];

	return Threshold_T / maxval_Ts.size();
}

//-----------------test--------------------//
int main()
{ 
   
	std::string path = "F:\\NoteImage\\Lena.jpg";
	cv::Mat src = imread(path, cv::IMREAD_GRAYSCALE);
	if (!src.data) { 
   
		std::cout << "Could not open or find the image" << std::endl;
		return -1;
	}

	cv::Mat dst;
	//对比一下opencv官方计算结果(显然结果是相同的)
	double thres1 = cv::threshold(src, dst, 0, 255, cv::THRESH_OTSU);
	double thres2 = Otsu_threshold(src);

	std::cout << "opencv = " << thres1 << " my = " << thres2;

	cv::waitKey(0);
	return 0;
}

处理结果:

在这里插入图片描述


与本博文有关的其他博文:
mask_otsu

自适应阈值Canny

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/184852.html原文链接:https://javaforall.net

(0)
上一篇 2022年8月31日 下午11:00
下一篇 2022年8月31日 下午11:00


相关推荐

  • 模拟电路与数字电路基础知识点总结

    模拟电路与数字电路基础知识点总结最近模电真的是让人头疼,模电马上就要结课了,而我的只是水平还停留在第一章第一节,总结起来就是老师讲课听不懂,我又不想听,再加上老师又不想把分给我们,所以我慌了,就再csdn上查找了一下有没有大佬对模电只是点进行过总结;世界之大,总有大佬的:废话不多说,直接上链接,赶快去膜拜:模拟电路与数字电路基础知识点总结千万不要挂科啊~!!!!!!!!!1…

    2022年6月20日
    31
  • 一推理一编程,“AI六小龙”MiniMax、月之暗面同推开源模型

    一推理一编程,“AI六小龙”MiniMax、月之暗面同推开源模型

    2026年3月12日
    2
  • acwing-9. 分组背包问题(分组背包)

    acwing-9. 分组背包问题(分组背包)有 N 组物品和一个容量是 V 的背包。每组物品有若干个,同一组内的物品最多只能选一个。每件物品的体积是 vij,价值是 wij,其中 i 是组号,j 是组内编号。求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。输出最大价值。输入格式第一行有两个整数 N,V,用空格隔开,分别表示物品组数和背包容量。接下来有 N 组数据:每组数据第一行有一个整数 Si,表示第 i 个物品组的物品数量;每组数据接下来有 Si 行,每行有两个整数 vij,wij,用空格隔开,分别表示第 i

    2022年8月9日
    6
  • c++如何获取系统当前时间(超级详细)

    c++如何获取系统当前时间(超级详细)voidgettime(){time_trawtime;structtm*ptminfo;time(&rawtime);ptminfo=localtime(&rawtime);printf(“current:%02d-%02d-%02d%02d:%02d:%02…

    2022年10月19日
    5
  • Python 数组截取

    Python 数组截取#数据源names=[‘a’,’b’,’c’,’d’,’e’,’f’]#正常获取print(names[1])#b#截取print(names[0:3])#[‘a’,’b’,’c’]print(names[3:10])#[‘d’,’e’,’f’]#截取:从指定开始直接到指定结尾print(names[3:])#[‘d’,’e’,’f’]print(names[:3])#[‘a’,’b’,’c’]#倒着切print(na

    2022年6月10日
    76
  • 微信小程序—-返回上一页刷新或当前页刷新

    微信小程序—-返回上一页刷新或当前页刷新HTML实现当前页面刷新首先我们都知道在HTML页面我们要实现当前页面刷新一般会怎么解决呢?1,reload()方法刷新当前页面;2,replace()方法刷新当前页面;3,页面自动刷新当前页面;三种实现js刷新当前页面的方法用法微信小程序—-返回上一页刷新或当前页刷新1,在实现效果之前,需要知道微信小程序的页面生命周期,不是很清楚的可以看微信小程序

    2022年6月11日
    1.7K

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号