大津阈值法原理_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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • java的this怎么理解

    java提供了一个this关键字,this关键字总是指向调用该方法的对象。根据this出现位置的不同,this作为对象的默认引用有两种情形:构造器中引用该构造器正在初始化的对象;在方法中引用调用该方法的对象。

  • SpringBoot项目打成war和jar的区别「建议收藏」

    SpringBoot项目打成war和jar的区别「建议收藏」首先给大家来讲一个我们遇到的一个奇怪的问题:1.我的一个springboot项目,用mvninstall打包成jar,换一台有jdk的机器就直接可以用java-jar项目名.jar的方式运行,没任何问题,为什么这里不需要tomcat也可以运行了?2.然后我打包成war放进tomcat运行,发现端口号变成tomcat默认的8080(我在server.port中设置端口8090)项目名称也…

  • 安卓手机如何查看分辨率_读取屏幕内容的安卓软件

    安卓手机如何查看分辨率_读取屏幕内容的安卓软件本文主要解决获取手机屏幕的大小:例子很简单,主要通过DisplayMetrics类来获取相关的信息,代码如下效果图:XML文件1.activity_main.xmlxmlns:tools=”http://schemas.android.com/tools”android:layout_width=”match_parent”android:layout_height=”match_pa…

  • HDU1160(LIS)

    HDU1160(LIS)

  • 最常用英语单词2000个[通俗易懂]

    最常用英语单词2000个[通俗易懂]最常用英语单词2000个1 a[ei,ə]art.一(个);任何一(个);每一(个)2 I[ai]pron.我3 ability[əbiliti]n.能力,本领;才能,才智4 able[eibəl]a.能够…的,得以…

  • 如何判断一个数是否为素数(判断一个数为素数)

    目录1.什么是质数?2.如何判断是否为质数?方法1方法2方法3方法41.什么是质数?首先来看质数的概念:质数(Primenumber),又称素数,指在大于1的自然数中,除了1和该数自身外,无法被其他自然数整除的数。(也可定义为只有1与该数本身两个正因数的数)图1数字12不是质数,而数字11是质数如上图所示,数字12可以将每4个分成一组,…

发表回复

您的电子邮箱地址不会被公开。

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