Ostu(大津法)二值化图像简介

一、前言

Ostu方法又名最大类间差方法,通过统计整个图像的直方图特性来实现全局阈值T的自动选取,其算法步骤为:

1)  先计算图像的直方图,即将图像所有的像素点按照0~255共256个bin,统计落在每个bin的像素点数量

2)  归一化直方图,也即将每个bin中像素点数量除以总的像素点

3)  i表示分类的阈值,也即一个灰度级,从0开始迭代

4)  通过归一化的直方图,统计0~i 灰度级的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例w0,并统计前景像素的平均灰度u0;统计i~255灰度级的像素(假设像素值在此范围的像素叫做背景像素) 所占整幅图像的比例w1,并统计背景像素的平均灰度u1;

5)  计算前景像素和背景像素的方差 g = w0*w1*(u0-u1) (u0-u1)

6)  i++;转到4),直到i为256时结束迭代

7)将最大g相应的i值作为图像的全局阈值

二、实现代码

Ostu算法实现函数为下面中的int getOstu(const Mat& in),其实在opencv中已经在threshold中实现了,下面代码也比较了两者的结果

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;

#include <iostream>

int getOstu(const Mat & in);

int main()
{
	Mat img = imread("id_card.jpg" ,0);
	Mat img_high_Light = imread("id_card2.jpg" ,0);
	Mat  dst , dst_HL;

	if(img.empty()  | img_high_Light.empty())
	{
		std::cout<<"Error!!";
		return -1;
	}

	std::cout<<"The return value of getOstu is: "<<getOstu(img);
	std::cout<<"\n"<<"The return value of opencv threshold is: "<<threshold(img , dst ,0,255,CV_THRESH_OTSU);//opencv已实现的大津法

	imshow("光照均匀的原图像" ,img);
	imshow("图像光照均匀的处理结果" , dst);

	threshold(img_high_Light , dst_HL ,0,255,CV_THRESH_OTSU);
	imshow("光照不均匀的原图像" ,img_high_Light );
	imshow("图像光照不均匀的处理结果",  dst_HL);


	waitKey(0);

	return 0;
}

int getOstu(const Mat & in)
{
	int rows = in.rows;
	int cols = in.cols;
	long size = rows * cols;

	float histogram[256] = {0};  
	for( int i = 0; i < rows; ++i) 
	{ 
		//获取第 i行首像素指针 
		const uchar * p = in.ptr<uchar>(i); 
		//对第i 行的每个像素(byte)操作 
		for( int j = 0; j < cols; ++j ) 
		{
			histogram[int(*p++)]++; 
		}
	}
	int threshold;      
	long sum0 = 0, sum1 = 0; //存储前景的灰度总和及背景灰度总和  
	long cnt0 = 0, cnt1 = 0; //前景的总个数及背景的总个数  
	double w0 = 0, w1 = 0; //前景及背景所占整幅图像的比例  
	double u0 = 0, u1 = 0;  //前景及背景的平均灰度  
	double variance = 0; //最大类间方差  


	double maxVariance = 0;  
	for(int i = 1; i < 256; i++) //一次遍历每个像素  
	{    
		sum0 = 0;  
		sum1 = 0;   
		cnt0 = 0;  
		cnt1 = 0;  
		w0 = 0;  
		w1 = 0;  
		for(int j = 0; j < i; j++)  
		{  
			cnt0 += histogram[j];  
			sum0 += j * histogram[j];  
		}  

		u0 = (double)sum0 /  cnt0;   
		w0 = (double)cnt0 / size;  

		for(int j = i ; j <= 255; j++)  
		{  
			cnt1 += histogram[j];  
			sum1 += j * histogram[j];  
		}  

		u1 = (double)sum1 / cnt1;  
		w1 = 1 - w0; // (double)cnt1 / size;  

		variance =  w0 * w1 *  (u0 - u1) * (u0 - u1);  
		if(variance > maxVariance)   
		{    
			maxVariance = variance;    
			threshold = i;    
		}   
	}    

	return threshold;    
}    
三、运行结果

调用函数getOstu和调用threshold所得到的图像全局阈值如下,可看出两者的结果非常接近,如下所示:

当所处理图像光照均匀时,这时的分割效果较好,如下所示



当处理的图像存在高照不均匀时,则ostu处理效果不是很好




  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
大津法二值化是一种常用的图像处理算法,它能有效地将图像转换为二值图像。在MATLAB中,可以通过使用Otsu算法实现大津法二值化。这个算法基于图像的灰度直方图,通过计算某个灰度值作为阈值时的类间方差最大化来确定最佳阈值。引用提供了一个MATLAB代码示例,可以通过输入图像路径来实现大津法二值化。在该代码中,使用了hist函数来获取每个像素值的数量,并根据这些数量计算出最佳阈值。实验结果表明,在处理特定类型的图像时,手动计算的阈值与MATLAB自带算法计算的阈值几乎一致。因此,可以使用MATLAB中的大津法二值化方法来有效地对图像进行二值化处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [MATLAB小技巧(3)otsu二值化分割算法](https://blog.csdn.net/sinat_34897952/article/details/124287380)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [matlab大津法二值化代码-imagebinarization:有效地对图像进行二值化](https://download.csdn.net/download/weixin_38708841/19076881)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [[matlab数字图像处理10]对一副图像进行二值化ostu算法等](https://blog.csdn.net/qq_46535765/article/details/126062684)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值