图像的二值化分割,otsu类间方差法

2023-11-18

      二值化图像指图像中的每个像素只取两个离散的值之一,用数学公式表示为:    

                      

                                                

      公式中,f(x,y)表示一幅数字图像,X,Y表示该图像中某像素的坐标值,T为 二值化的阈值,表示经过阈值运算后的二值化图像,这里0和1仅仅是一个抽象表示,并非实际像素值,它可以代表白色和黑色,也可以代表红色和蓝色。

        OTSU最大类间方差法是由日本学者大津(OTSU)于1979年提出的,是一种自适应的阈值确定的方法,由于它计算相对简单,时间消耗也明显少于其他阈值化方法。最大类间方差法是在最小二乘法原理基础上推导出来的,其基本思路是将直方图在某一阈值处分割成两组,对于某阈值,若被分成的两组之间的方差为最大时,则确定其为分割阈值。

设一幅图像的灰度值为1-m级,灰度值i的像素为ni,此时得到总像素数N和各值的概率为:

                                                                       

                                                                                      

然后用后将其分成两组C0={1-k}和C1={k+1~m},C0和C1产生的概率为:

                                             

                       

C0组和C1组的平均值:

                                                      

                             

 式中:只是整体图像的平均值,是阀值为k时灰度的平均值。因此全部采样的灰度平均值为:

                                                                   


 则类间方差由下式求出:

                              

          从1到m改变k值,求Max{},此时的k值便是所求阀值。


代码实现,这里给出基于opencv的部分算法代码:

int otsuThreshold(IplImage *frame)
{

    int width = frame->width;
	int height = frame->height;
	int pixelCount[256];
	float pixelPro[256];
	int i, j, pixelSum = width * height, threshold = 0;
	uchar* data = (uchar*)frame->imageData;

	for(i = 0; i <256; i++)
	{
		pixelCount[i] = 0;
		pixelPro[i] = 0;
	}

	//统计灰度级中每个像素在整幅图像中的个数
	for(i = 0; i < height; i++)
	{
		for(j = 0;j < width;j++)
		{
		pixelCount[(int)data[i * frame->widthStep+ j]]++;
		}
	}
	
	//计算每个像素在整幅图像中的比例
	for(i = 0; i < 256; i++)
	{
		pixelPro[i] = (float)pixelCount[i] / pixelSum;
	}

	//遍历灰度级[0,255]
	float w0, w1, u0tmp, u1tmp, u0, u1, u, 
			deltaTmp, deltaMax = 0;
	for(i = 0; i < 256; i++)
	{
		w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
		for(j = 0; j < 256; j++)
		{
			if(j <= i)   //背景部分
			{
				w0 += pixelPro[j];
				u0tmp += j * pixelPro[j];
			}
			else   //前景部分
			{
				w1 += pixelPro[j];
				u1tmp += j * pixelPro[j];
			}
		}
		u0 = u0tmp / w0;
		u1 = u1tmp / w1;
		u = u0tmp + u1tmp;
		deltaTmp = 
			w0 * pow((u0 - u), 2) + w1 * pow((u1 - u), 2);
		if(deltaTmp > deltaMax)
		{
			deltaMax = deltaTmp;
			threshold = i;
		}
	}
	return threshold;
}

完整的程序我已经上传了,其实就是加入了输入输出部分 (∩_∩):

http://download.csdn.net/detail/emiyasstar__/3723042

实验结果:

左边是肤色模型建模的灰度图,右边是分割结果,效果还不错:






本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图像的二值化分割,otsu类间方差法 的相关文章

随机推荐

  • v-model是什么?怎么使用?

    v model是什么 怎么使用 v model用于表单数据的双向绑定 其实它就是一个语法糖 这个背后就做了两个操作 v bind绑定一个value属性 v on指令给当前元素绑定input事件 v model很好地体现了vue双向绑定的理念
  • C++11 chrono计时

    我的C 文章列表 C 中Duration Time point和Clocks 万里归来少年心的博客 CSDN博客 time point C 11中的chrono库 实现时间相关的功能 1 time point time point表示一个时
  • 什么是php 服务器地址,服务器地址是什么

    服务器地址是服务器的ip地址 IP地址就是给每个连接在互联网上的主机分配的一个32位地址 有这种地址 才保证了用户在连网的计算机上操作时 能够高效而且方便地从千千万万台计算机中选出所需的对象来 本文操作环境 Windows7系统 Dell
  • AI 对抗超级细菌:麦克马斯特大学利用深度学习发现新型抗生素 abaucin

    内容一览 鲍曼不动杆菌是一种常见的医院获得性革兰氏阴性病原体 通常表现出多重耐药性 利用传统方法 发现抑制此菌的新型抗生素很困难 但利用机器学习可以快速探索化学空间 从而增加发现新型抗菌分子的可能性 近期 国际期刊 Nature Chemi
  • Java生成纳秒时间戳

    记一次生成高精度时间戳 类似与 net的时间戳 码着备忘 long timestamp System currentTimeMillis 1000000L System nanoTime 1000000L System currentTim
  • 函数的防抖与节流

    一 防抖与节流的联系 相同点 防抖 Debounce 和节流 Throttle 都是用来控制某个函数在一定时间内触发次数 两者都是为了减少触发频率 以便提高性能以及避免资源浪费 不同点 节流是第一个说了算 后续都会被节流阀屏蔽掉 防抖是最后
  • (小陈c语言)井字棋-初步实现以及改进方向

    作为小学上课偷偷和同桌在草稿本上玩的小游戏 井字棋 如今在电脑上也可以自己写出来玩 如图 不要惊讶 下面我们来看看怎么实现这个代码 正文开始 1 菜单界面 用多个printf 来打印即可 注意中间最好是空的不要连着字 void menu p
  • CVPR2020-RFANet-图像超分辨率新网络

    创新点都比较小 提升也很小 有种炒冷饭的感觉 论文地址 http openaccess thecvf com content CVPR 2020 papers Liu Residual Feature Aggregation Network
  • pycharm GIT 账号密码输入错误如何更改

    pycharm GIT 账号密码输入错误如何更改 第一次在pycharm中 输入git的账户或者密码出现错误 下一次pycharm系统会记住你输入错误的账户和密码 The requested URL returned error 500 只
  • python的日志logging模块使用总结

    文章转载与 http outofmemory cn code snippet 450 python rizhi logging module usage summary 1 简单的将日志打印到屏幕 import logging loggin
  • Android5——活动的生命周期方法

    1 活动的生命周期方法 onCreate 会在活动第一次被创建的时候使用 onStart 会在活动由不可见变为可见的时候调用 OnResume 会在活动准备好和用户进行交互的时候调用 此时的活动一定位于返回栈的栈顶 并且处于运行状态 onP
  • 简单两步解决Python的NLTK库DATA安装问题

    前言 本人使用Anaconda集成开发环境 已经安装有NLTK库 在使用NLTK最简单的分词功能时报错 查询错误 得知是没有安装NLTK的数据包 系统推荐使用以下命令 import nltk nltk download 用了之后弹出窗口 出
  • ROS 第四天 ROS中的关键组件

    1 Launch文件 通过XML文件实现多节点的配置和启动 可自动启动ROS Master
  • word文档中如何添加目录

    如果word文档的内容较多 结构复杂 那么在文档首页设置一个目录链接是非常有必要的 本文将介绍如何添加此目录 1 设置标题 在文档中选择将在目录中显示的内容 将之设置为 标题1 标题2 或 标题3 等 其中 标题1 代表一级标题 应为顶级目
  • 如何在 Java 中调用 MATLAB 代码

    文章目录 测评 完整源代码 运行环境 MATLAB R2022a Java 8 1 8 0 311 IntelliJ IDEA 2022 2 1 Ultimate Edition Maven 3 8 3 Windows 10 教育版 64位
  • ios 删除无用证书

    1 前往文件夹 Library MobileDevice Provisioning Profiles 然后可以删除里面的所有文件 然后就可以根据自己的需求重新下载了
  • STM32之_keil 编译内存大小解析

    Program Size Code 28784 RO data 6480 RW data 60 ZI data 3900 的含义 1 Code 程序所占用的FLASH大小 存储在FLASH 2 RO data Read only data
  • 简单的c++ UDP类 + 多线程 win32编程

    UdpClient h include Thread h class IUdpRecvCallback public virtual void OnRecv const char buf USHORT len const char from
  • 基恩士PLC KV8000+XH16EC总线控制,全ST程序实例

    基恩士PLC KV8000 XH16EC总线控制 全ST程序实例 本人自己开发全程序无加密 公司级框架 功能齐全 提供项目源码框架FB源码 触摸屏源码 需要一定ST基础才能看懂 重在分享编程思想 没用过该控制器的请慎拍 请使用11 10版本
  • 图像的二值化分割,otsu类间方差法

    二值化图像指图像中的每个像素只取两个离散的值之一 用数学公式表示为 公式中 f x y 表示一幅数字图像 X Y表示该图像中某像素的坐标值 T为 二值化的阈值 表示经过阈值运算后的二值化图像 这里0和1仅仅是一个抽象表示 并非实际像素值 它