学习DIP第55天

转载请标明本文出处:***http://blog.csdn.net/tonyshengtan ***,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发:https://github.com/Tony-Tan/DIPpro

更多图像处理机器学习内容请访问最新网站www.tony4ai.com

#开篇废话

废话开始,今天介绍OTSU算法,本算法比前面给出的算法更能够给出数学上的最佳阈值,不需要任何输入附加参数、与同样不需要输入附加参数的迭代均值和均值阈值来比较,OTSU给出的阈值能使分类更加均匀。

阈值处理将灰度值分为两类,而对于分类问题,已有的一种最优闭合解–贝叶斯决策规则。

#贝叶斯决策规则

首先介绍下贝叶斯公式的形象化理解,考虑下图

上面的12幅图中有手枪和弹夹,只有弹夹和手枪出现在同一个盒子的时候才有杀伤力,也就是你拿到一个盒子,你不知道里面是什么,有可能是枪,有可能是弹夹,有可能同时有枪和弹夹。下面来从概率学角度分析

设盒子里有枪为事件A,那么A出现的概率设为p(A)p(A)p(A)。

设盒子里有弹夹为事件B,那么B出现的概率设为p(B)p(B)p(B)。

那么同时出现事件A和事件B的概率为p(AB)p(AB)p(AB)

看图可以知道

$p(A)=\frac{8}{12}=\frac{2}{3} $..........(1)
$p(B)=\frac{7}{12} $..........(2)
$p(AB)=\frac{3}{12}=\frac{1}{4} $..........(3)

考虑我们随机抽出一个盒子,先拿出一个东西,比如先拿出一把枪,那么也就是事件A发生了,那么我们继续从盒子里拿东西,有可能拿到弹夹,也有可能啥也没有,那么拿到弹夹的概率就如下:

$p(B|A)=\frac{3}{8} $..........(4)

同理,如果先拿出来的是个弹夹,那么接下来拿出枪的概率是:

$p(A|B)=\frac{3}{7} $..........(5)

结合(1)(2)(3)(4)(5),可以得到:

$p(AB)=p(A|B)*p(B)=p(B|A)*p(A) $..........(6)


假设下面情形:

已知拿出枪的概率是:

$p(A)=\frac{2}{3} $

拿出枪以后拿出弹夹的概率

$p(B|A)=\frac{3}{8} $

拿出弹夹的概率:

$p(B)=\frac{7}{12} $

求拿出弹夹以后拿出枪的概率

$p(A|B)=\frac{p(B|A)*p(A)}{p(B)} $

以上就是贝叶斯公式的一般形式,更复杂的形式会在后面的文章中详细介绍。(更复杂的形式是指盒子里有枪,子弹,弹夹,手榴弹。。。。。。)

#数学原理

OTSU算法可以基于直方图计算,考虑灰度级为{0,1,2…L-1}大小为$M \times N 的图像,设的图像,设的图像,设n_i $为灰度级为i的像素的总数量,那么:

$M \times N=\sum^{L-1}_{i=0}n_i $
$p(n_i)=\frac{n_i}{M \times N} $
$\sum^{L-1}_{i=0}p_i=1 $

假设阈值为k将直方图分成两部分。

部分1(C1)(C_1)(C1​)的概率为:

$p_1(k)=\sum^{k}_{i=0}p_i $

部分2(C2)(C_2)(C2​)的概率为:

$p_2(k)=\sum^{L-1}_{i=k+1}p_i $

部分1(C1)(C_1)(C1​)的平均数:

$m_1(k)=\sum^{k}_{i=0}i*P(i|C_1)=\sum^{k}_{i=0}i*\frac{P(C_1|i)*P(i)}{P(C_1)} $

$P(C_1|i) 的值为1,因为的值为1,因为的值为1,因为i 是属于是属于是属于C_1 的,所以发生的,所以发生的,所以发生i 以后发生以后发生以后发生C_1 $的概率是100%,所以

$m_1(k)=\frac{1}{P_1(k)} \sum^{k}_{i=0}i*p_i $

部分2(C2)(C_2)(C2​)的平均数:

$m_2(k)=\frac{1}{P_2(k)} \sum^{L-1}_{k+1}i*p_i $

全图的均值

$m_G=\sum^{L-1}_{i=0}iP_i $

上面的式子可以由下面验证:

$P_1m_1+P_2m_2=m_G $
$P_1+P_2=1 $

下面就是关键部分了,如何评价一个阈值的好坏,提出一个阈值,将像素灰度分为两类,通过以下的公式来评价阈值质量:

$\eta=\frac{\delta_B^2}{\delta_G^2} $
$\delta_G^2=\sum^{L-1}_{i=0}(i-m_G)^2*p_i $

δB2\delta_B^2δB2​是类间方差,其定义为:

$\delta_B^2=P_1(m_1-m_G)^2+P_2(m_2-m_G)^2 $

公式还可以写成:

$\delta^2_B=P_1P_2(m_1-m_2)^2=\frac{P_1(m_1-m_G)^2}{1-P_1} $

于是最佳阈值$k^* $由下面得出:

$\delta^2_B(k^*)=max_{0\leq k \leq L-1}\delta^2_B(k) $

通过上式可以通过迭代计算出最佳的k值。使用k作为阈值,对图像进行处理。

#代码实现

/*
*OTSU 算法
*otsu 算法使用贝叶斯分类原理得到最好聚类
*
*
*/
//归一化直方图 void setHist2One(double *hist_d,double *dst_hist_d){
double sum=0.0;
for(int i=0;i<GRAY_LEVEL;i++)
sum+=hist_d[i];
if(sum!=0)
for(int i=0;i<GRAY_LEVEL;i++)
dst_hist_d[i]=hist_d[i]/sum; }
//计算公式中最大的deta,并返回直方图灰度
double findMaxDeta(double *hist_d){
double max_deta=-1.0;
double max_deta_location=0.0;
double m_g=0.0; for(int i=0;i<GRAY_LEVEL;i++)
m_g+=i*hist_d[i]; for(int i=0;i<GRAY_LEVEL;i++){
double p1=0.0;
double m1=0.0;
double deta=0.0;
for(int j=0;j<=i;j++){
p1+=hist_d[j];
m1+=j*hist_d[j];
}
deta=p1*(m1-m_g)*(m1-m_g)/(1-p1);
if(deta>max_deta){
max_deta_location=i;
max_deta=deta;
}
}
return max_deta_location;
}
void OTSUThreshold(double *src,double *dst,int width,int height,int type){
int hist[GRAY_LEVEL];
double hist_d[GRAY_LEVEL];
setHistogram(src, hist, width, height);
Hist_int2double(hist, hist_d);
setHist2One(hist_d, hist_d);
double threshold=findMaxDeta(hist_d);
Threshold(src, dst, width, height, threshold, type);
}

#观察结果

原图:

![这里写图片描述](https://img-blog.csdn.net/20150308152743862)
![这里写图片描述](https://img-blog.csdn.net/20150308152907539)

加入1%的高斯噪声:

![这里写图片描述](https://img-blog.csdn.net/20150308152918272)
![这里写图片描述](https://img-blog.csdn.net/20150308152814765)

加入3%的高斯噪声:

![这里写图片描述](https://img-blog.csdn.net/20150308152827323)
![这里写图片描述](https://img-blog.csdn.net/20150308152836777)

加入5%的高斯噪声:

![这里写图片描述](https://img-blog.csdn.net/20150308153000860)
![这里写图片描述](https://img-blog.csdn.net/20150308153012264)

加入7%的高斯噪声:

![这里写图片描述](https://img-blog.csdn.net/20150308152915106)
![这里写图片描述](https://img-blog.csdn.net/20150308152932001)

加入9%的高斯噪声:

![这里写图片描述](https://img-blog.csdn.net/20150308153053245)
![这里写图片描述](https://img-blog.csdn.net/20150308153102277)

加入11%的高斯噪声:

![这里写图片描述](https://img-blog.csdn.net/20150308153112137)
![这里写图片描述](https://img-blog.csdn.net/20150308153008599)

lena:

![这里写图片描述](https://img-blog.csdn.net/20150308153300433)

baboon:

![这里写图片描述](https://img-blog.csdn.net/20150308153428432)

#总结

OTSU算法产生的阈值是数学角度上的最佳分类,数学基础的贝叶斯公式,但应用也有一定的局限性,比如,前面说过最多的,对全局阈值,目标与背景的大小关系,当目标和背景大小相差很多时,或者噪声很大的时候,对OTSU产生影响较大。

待续。。。

更多人工智能机器学习,计算机视觉知识欢迎访问:

理论:


技术


随笔

灰度图像--图像分割 阈值处理之OTSU阈值的更多相关文章

  1. 灰度图像的自动阈值分割(Otsu 法)(转载)

    灰度图像的自动阈值分割(Otsu 法) 机器视觉领域许多算法都要求先对图像进行二值化.这种二值化操作阈值的选取非常重要.阈值选取的不合适,可能得到的结果就毫无用处.今天就来讲讲一种自动计算阈值的方法. ...

  2. 【图像算法】七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)

    图像算法:图像阈值分割 SkySeraph Dec 21st 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified Da ...

  3. 图像处理------基于Otsu阈值二值化

    一:基本原理 该方法是图像二值化处理常见方法之一,在Matlab与OpenCV中均有实现. Otsu Threshing方法是一种基于寻找合适阈值实现二值化的方法,其最重 要的部分是寻找图像二值化阈值 ...

  4. opencv python 图像二值化/简单阈值化/大津阈值法

    pip install matplotlib 1简单的阈值化 cv2.threshold第一个参数是源图像,它应该是灰度图像. 第二个参数是用于对像素值进行分类的阈值, 第三个参数是maxVal,它表 ...

  5. 机器学习进阶-阈值与平滑-图像阈值 1. cv2.threshold(进行阈值计算) 2. 参数type cv2.THRESH_BINARY(表示进行二值化阈值计算)

    1. ret, dst = cv2.thresh(src, thresh, maxval, type) 参数说明, src表示输入的图片, thresh表示阈值, maxval表示最大值, type表 ...

  6. .Net CLR GC 动态加载短暂堆阈值的计算及阈值超量的计算

    前言: 很多书籍或者很多文章,对于CLR或者GC这块只限于长篇大论的理论性概念,对于里面的如何运作模式,却几乎一无所知.高达近百万行的CPP文件,毕竟读懂的没有几个.以下取自CLR.Net 6 Pre ...

  7. 灰度图像--图像分割 阈值处理之P-Tile阈值

    学习DIP第53天 转载请标明本文出处:***http://blog.csdn.net/tonyshengtan ***,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发:http ...

  8. 灰度图像的自动阈值分割(Otsu 法)

    关于otsu分割方法,这个文章讲的是最好的,清晰易懂,一看就是作者认真思考过的. 因为在看这个算法的时候我就想,如果一个很大的图像上,大部分像素值都在0 - 50范围内,但是有很小一块像素值在240的 ...

  9. 七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)

    http://blog.csdn.net/xw20084898/article/details/17564957 一.工具:VC+OpenCV 二.语言:C++ 三.原理 otsu法(最大类间方差法, ...

随机推荐

  1. X86逆向9:通过关键常量破解

    本章将讲解一下关于关键全局变量的一些内容,关键的全局变量对于软件的破解非常的有用,找到了关键全局变量并改写它同样可以完成完美爆破一个程序,这里我将使用CM小例子来讲解搜索关键变量的一些技巧,最后我们来 ...

  2. Web前端开发JavaScript基础

    JavaScript 一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型,它的解释器被称为JavaScript引擎,是浏览器的一部分,并且是被广泛用于客户端的脚本语言,JavaS ...

  3. maraidb忘记数据密码

    一.概述 服务器上安装了maraidb 数据库,但是很久未使用过它,需要使用时,忘记了密码, 此时可以给它重新设置密码. 二.操作 修改密码 修改 /etc/my.cnf,修改下图红色区域位置,修改成 ...

  4. Java 代码运行顺序

    1.静态代码块,只执行一次,从上到下,先父类后子类 2.父类构造代码块,从上到下,然后父类构造方法,执行次数与实例化次数相关 3.子类构造代码块,从上到下,然后子类构造方法,执行次数与实例化次数相关

  5. jvm GC:垃圾回收的测试与分析

    实验环境: (1)Java版本以及模式: java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0 ...

  6. Highcharts折线图_结合ajax实现局部刷新

    1.首先,在https://www.hcharts.cn/下载Highcharts的组件. 2.然后,引用 <script src="../code/highcharts.js&quo ...

  7. QT获取屏幕分表率(PC、安卓)

    QRect screenRect = QGuiApplication::primaryScreen()->geometry(); double devicePixelRatio = QGuiAp ...

  8. 嵌套For循环性能优化

    请对以下的代码进行优化 for (int i = 0; i < 1000; i++) for (int j = 0; j < 100; j++) for (int k = 0; k < ...

  9. 转:git常用操作

    转自:https://www.cnblogs.com/donghaojun/p/10906981.html 开发常用git指令:git init  # 初始化本地git环境 git clone xxx ...

  10. JavaScript笔记(3)

    字典(Array对象) Array对象当字典使用时,.length属性就不能使用了 如果想访问对象元素,不能使用索引,只能使用key 如果遍历字典,只能使用for--in语句 字典是另一种可变容器模型 ...