大津阈值法原理_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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • rcep协议内容_ptp协议

    rcep协议内容_ptp协议展开全部(1)合同的含义合同是当事人或当事双方之间设立、变更、终止民事关系的协议。依法62616964757a686964616fe78988e69d8331333363373036成立的合同,受法律保护。合同具有如下法律特征:①合同是两个或两个以上的、法律地位平等的当事人意思表示一致的协议;②合同以产生、变更或终止债权债务关系为目的;③合同是一种民事法律行为。在合同中,一般用甲方、乙方来指代交易…

    2022年9月6日
    3
  • MariaDB安装教程

    MariaDB安装教程注:从MariaDB10.4.3开始,不再提供预构建的数据目录,并且用户需要运行mysql_install_db.exe来创建数据目录1、解压到自定义路径E:\MariaDB\mariadb-10.5.4-winx642、将其中的bin加入path系统环境路径3、用管理员方式打开cmd,并打开bin目录4、输入mysql_install_db.exe–datadir=E:\MariaDB\mariadb-10.5.4-winx64\data–service=MyMar..

    2022年6月14日
    34
  • java StringBuffer和StringBuilder

    java StringBuffer和StringBuilder一、前言我们在实际的开发中,如果需要进行字符串的频繁拼接,会出现以下问题:java中的字符串是不可变的,每一次拼接都会产生新字符串。这样会占用大量的方法区内存。造成内存空间的浪费。eg.Strings=”abc”;s+=”hello”;就以上两行代码,就导致在方法区字符串常量池当中创建了3个对象:”abc””hello””abchello”因此引出StringBuffer和StringBuilder可变字符串!二、如何优化StringBuffer和StringBuild

    2022年7月17日
    11
  • Tomcat配置阿里云SSL证书[通俗易懂]

    Tomcat配置阿里云SSL证书[通俗易懂]记录一次令我蛋疼的tomcat配置SSL证书在阿里云平台获取到SSL证书,并下载,里面有两个文件将证书copy到tomcat下的conf文件夹下,然后配置server.xml文件修改内容如下:<Connectorport=”443″protocol=”org.apache.coyote.http11.Http11NioProtocol”maxTh…

    2022年10月3日
    0
  • 0x7ffffffff什么意思(y9000x)

    运行之后发现:0x7FFFFFFF对应int.MaxValue即21474836470xFFFFFFFF对应uint.MaxValue即42949672950x7FFF对应short.MaxValue即327670xFFFF对应ushort.MaxValue即655350x7F对应sbyte.MaxValue即1270xFF对应byt…

    2022年4月12日
    73
  • Android之CardView[通俗易懂]

    Android之CardView[通俗易懂]文章目录一、常用属性二、属性效果展示三、案例展示具体代码:1、一个最简单的示例:2、复杂化四、案例1、布局搭建2、实体类创建3、功能实现4、适配CardView继承FrameLayout一、常用属性1、cardBackgroundColor设置背景色CardView是View的子类,View一般使用Background设置背景色,为什么还要单独提取出一个属性让我们来设置背景色呢?为了…

    2022年10月11日
    0

发表回复

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

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