OSTU二值化算法
介绍
Ostu方法又名最大类间差方法,通过统计整个图像的直方图特性来实现全局阈值T的自动选取,其算法步骤为:
先计算图像的直方图,即将图像所有的像素点按照0~255共256个bin,统计落在每个bin的像素点数量
归一化直方图,也即将每个bin中像素点数量除以总的像素点
i表示分类的阈值,也即一个灰度级,从0开始迭代
通过归一化的直方图,统计0~i 灰度级的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例w0,并统计前景像素的平均灰度u0;统计i~255灰度级的像素(假设像素值在此范围的像素叫做背景像素) 所占整幅图像的比例w1,并统计背景像素的平均灰度u1;
计算前景像素和背景像素的方差 g = w0*w1*(u0-u1) (u0-u1)
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二值化算法的更多相关文章
- Wellner 自适应阈值二值化算法
参考文档: Adaptive Thresholding for the DigitalDesk.pdf Adaptive Thresholding Using the Integral I ...
- sauvola二值化算法研究
sauvola二值化算法研究 sauvola是一种考虑局部均值亮度的图像二值化方法, 以局部均值为基准在根据标准差做些微调.算法实现上一般用积分图方法 来实现.这个方法能很好的解决全局阈值方法的短 ...
- 一种局部二值化算法:Sauvola算法
之前接触过全局二值化(OTSU算法),还有OPENCV提供的自适应二值化,最近又了解到一种新的局部二值化算法,Sauvola算法. 转载自:http://www.dididongdong.com/ar ...
- 基于Simple Image Statistics(简单图像统计,SIS)的图像二值化算法。
这是个简单的算法,是全局二值算法的一种,算法执行速度快. 算法过程简单描述如下: 对于每一个像素,做如下处理 1.计算当前像素水平和垂直方向的梯度. (two gradients are calcul ...
- [转载+原创]Emgu CV on C# (四) —— Emgu CV on 全局固定阈值二值化
重点介绍了全局二值化原理及数学实现,并利用emgucv方法编程实现. 一.理论概述(转载,如果懂图像处理,可以略过,仅用作科普,或者写文章凑字数) 1.概述 图像二值化是图像处理中的一项基本技术,也 ...
- 【转】Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化
局部自适应阈值二值化 相对全局阈值二值化,自然就有局部自适应阈值二值化,本文利用Emgu CV实现局部自适应阈值二值化算法,并通过调节block大小,实现图像的边缘检测. 一.理论概述(转载自< ...
- [转载+原创]Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化
局部自适应阈值二值化 相对全局阈值二值化,自然就有局部自适应阈值二值化,本文利用Emgu CV实现局部自适应阈值二值化算法,并通过调节block大小,实现图像的边缘检测. 一.理论概述(转载自< ...
- adaptiveThreshold自适应二值化源码分析
自适应二值化介绍: 二值化算法是用输入像素的值I与一个值C来比较,根据比较结果确定输出值. 自适应二值化的每一个像素的比较值C都不同,比较值C由这个像素为中心的一个块范围计算在减去差值delta得到. ...
- Win8 Metro(C#)数字图像处理--2.59 P分位法图像二值化
原文:Win8 Metro(C#)数字图像处理--2.59 P分位法图像二值化 [函数名称] P分位法图像二值化 [算法说明] 所谓P分位法图像分割,就是在知道图像中目标所占的比率Rat ...
随机推荐
- iOS 7.1 UITapGestureRecognizer 不好用的解决办法
UITapGestureRecognizer *tap3 = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(o ...
- json字符串和json对象的转换
http://www.json.org/提供了一个json2.js,这样ie8(兼容模式),ie7和ie6就可以支持JSON对象以及其stringify()和parse()方法: parse用于从一个 ...
- Nginx/LVS/HAProxy 负载均衡软件的优缺点对比
Nginx/LVS/HAProxy是目前使用最广泛的三种负载均衡软件,一般对负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术,具体的应用需求还得具体分析. 如果是中小型的Web应用,比 ...
- Tornado实战
抽屉之Tornado实战(1)--分析与架构 抽屉之Tornado实战(2)--数据库表设计 抽屉之Tornado实战(3)--注册 抽屉之Tornado实战(4)--发帖及上传图片 抽屉之Torna ...
- Andrew Ng机器学习编程作业:Multi-class Classification and Neural Networks
作业文件 machine-learning-ex3 1. 多类分类(Multi-class Classification) 在这一部分练习,我们将会使用逻辑回归和神经网络两种方法来识别手写体数字0到9 ...
- 001-es6变量声明、解构赋值、解构赋值主要用途
一.基本语法 1.1.声明变量的六种方法 参看地址:http://es6.ruanyifeng.com/#docs/let let:局部变量,块级作用域,声明前使用报错 var:全局变量,声明前使用 ...
- MSSQL获取昨天,本周,本月。。。
特别说明下:以下统计本周数据时,星期天是作为下周的第一天,而不是本周最后一天,因此你把星期天作为本周最后一天时,你需要在getDate()的基础上减一天,如dateadd('day', -1, get ...
- 用Maven构建Mahout项目实现协同过滤ItemCF--集群版
本文来自于:http://blog.fens.me/hadoop-mahout-mapreduce-itemcf/ 前言 Mahout是Hadoop家族一员,从血缘就继承了Hadoop程序的特点,支持 ...
- Django基础——模板层(template) (Day67)
阅读目录 变量 标签 自定义过滤器和标签 模板层(template) 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. 1 2 3 4 ...
- go——反射
反射(reflect)让我们能在运行期探知对象地类型信息和内存结构,这从一定程度上弥补了静态语言在动态行为上地不足.和C数据结构一样,Go对象头部并没有类型指针,通过其自身是无法在运行期获知任何类型相 ...