介绍

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值作为图像的全局阈值

#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("mobile2.jpeg" ,0);
Mat img_high_Light = imread("mobile3.jpeg" ,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("origin" ,img);
imshow("new" , dst); waitKey(0); threshold(img_high_Light , dst_HL ,0,255,CV_THRESH_OTSU);
imshow("origin" ,img_high_Light );
imshow("new", 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;
}

缺陷

OSTU算法在处理光照不均匀的图像的时候,效果会明显不好,因为利用的是全局像素信息。

OSTU二值化算法的更多相关文章

  1. Wellner 自适应阈值二值化算法

    参考文档: Adaptive Thresholding for the DigitalDesk.pdf       Adaptive Thresholding Using the Integral I ...

  2. sauvola二值化算法研究

    sauvola二值化算法研究   sauvola是一种考虑局部均值亮度的图像二值化方法, 以局部均值为基准在根据标准差做些微调.算法实现上一般用积分图方法 来实现.这个方法能很好的解决全局阈值方法的短 ...

  3. 一种局部二值化算法:Sauvola算法

    之前接触过全局二值化(OTSU算法),还有OPENCV提供的自适应二值化,最近又了解到一种新的局部二值化算法,Sauvola算法. 转载自:http://www.dididongdong.com/ar ...

  4. 基于Simple Image Statistics(简单图像统计,SIS)的图像二值化算法。

    这是个简单的算法,是全局二值算法的一种,算法执行速度快. 算法过程简单描述如下: 对于每一个像素,做如下处理 1.计算当前像素水平和垂直方向的梯度. (two gradients are calcul ...

  5. [转载+原创]Emgu CV on C# (四) —— Emgu CV on 全局固定阈值二值化

    重点介绍了全局二值化原理及数学实现,并利用emgucv方法编程实现. 一.理论概述(转载,如果懂图像处理,可以略过,仅用作科普,或者写文章凑字数)  1.概述 图像二值化是图像处理中的一项基本技术,也 ...

  6. 【转】Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化

    局部自适应阈值二值化 相对全局阈值二值化,自然就有局部自适应阈值二值化,本文利用Emgu CV实现局部自适应阈值二值化算法,并通过调节block大小,实现图像的边缘检测. 一.理论概述(转载自< ...

  7. [转载+原创]Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化

    局部自适应阈值二值化 相对全局阈值二值化,自然就有局部自适应阈值二值化,本文利用Emgu CV实现局部自适应阈值二值化算法,并通过调节block大小,实现图像的边缘检测. 一.理论概述(转载自< ...

  8. adaptiveThreshold自适应二值化源码分析

    自适应二值化介绍: 二值化算法是用输入像素的值I与一个值C来比较,根据比较结果确定输出值. 自适应二值化的每一个像素的比较值C都不同,比较值C由这个像素为中心的一个块范围计算在减去差值delta得到. ...

  9. Win8 Metro(C#)数字图像处理--2.59 P分位法图像二值化

    原文:Win8 Metro(C#)数字图像处理--2.59 P分位法图像二值化  [函数名称]   P分位法图像二值化 [算法说明]   所谓P分位法图像分割,就是在知道图像中目标所占的比率Rat ...

随机推荐

  1. Bouncy Castle Crypto API c# port

    Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包.它支持大量的密码术算法,并提供 JCE 1.2.1 的实现.现在有了C#的版本.下面是网站上的介绍 This port ...

  2. 第一只python爬虫

    import urllib.request response = urllib.request.urlopen("http://www.baidu.com") html = res ...

  3. tfs+git

    TFS+GIT 一:背景介绍 技术团队的代码管理工具原来使用的是纯TFS方案,使用两年后发现一些问题:体积太大,每次新建一个分支需要本地下载一份代码:操作不便,功能分支的建立.合并不方便,本地有很多同 ...

  4. 基于GTID的主从架构异常处理流程

    通常情况下我们主库的binlog只保留7天,如果从库故障超过7天以上的数据没有同步的话,那么主从架构就会异常,需要重新搭建主从架构. 本文就简单说明下如何通过mysqldump主库的数据恢复从库的主从 ...

  5. 《挑战程序设计竞赛》2.2 贪心法-其它 POJ3617 3069 3253 2393 1017 3040 1862 3262

    POJ3617 Best Cow Line 题意 给定长度为N的字符串S,要构造一个长度为N的字符串T.起初,T是一个空串,随后反复进行下列任意操作: 从S的头部(或尾部)删除一个字符,加到T的尾部 ...

  6. 【我的Android进阶之旅】 Android Studio插件之Jenkins插件介绍

    一Jenkins插件功能介绍 1Jenkins任务列表 2切换Jenkins分组 3构建Jenkins任务 4进入构建Jenkins任务的页面 5进入最后一次构建Jenkins任务的页面 6增加Jen ...

  7. Java加密技术(四)非对称加密算法RSA

    RSA      这样的算法1978年就出现了.它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作.也非常流行.算法的名字以发明者的名字命名:Ron Rivest, AdiShamir ...

  8. Linux学习笔记(4)磁盘分区(fdisk)、挂载与文件系统命令

    Linux学习笔记(4)磁盘分区(fdisk).挂载与文件系统命令 1.磁盘分区是怎么表示的? 1.1 对于IDE接口,第一主盘为hda,第1从盘为hdb,第1从盘的第1个分区为hdb1 1.2 对于 ...

  9. MySQL读写分离之amoeba

    MySQL读写分离之amoeba主从复制的搭建环境参考:http://www.cnblogs.com/fansik/p/5270334.htmlamoeba依赖于jdk环境:jdk环境搭建参考:htt ...

  10. go——切片(二)

    切片是一种数据结构,这种数据结构便于使用和管理数据集合. 切片是围绕动态数组的概念构建的,可以按需自动增长和缩小. 切片的动态增长是通过内置函数append来实现的.这个函数可以快速且高效地增长切片. ...