OTSU算法/大津法/最大类间方差法 python实现

1. 介绍

OTSU算法是由日本学者大津于1979年提出的一种对图像进行二值化的高效算法,也称为大津法,最大类间方差法。它根据图像的灰度特性而分为背景和前景两部分,背景和前景之间的像素值波动性越大,说明这两部分的差别越大,反之,差别越小。简而言之,算法根据图像的信息自适应地确定二值化阈值。

2. 算法原理

假设输入图像为灰度图像 III ,图像宽高分别为 www 和 hhh ,灰度级为 LLL 。
则图像包含的像素总数为
N=w×hN=w \times hN=w×h
灰度范围 i=0,1,2,...,L−1i=0,1,2,...,L-1i=0,1,2,...,L−1
根据图像像素数 NNN 和灰度范围 [0,L−1][0,L-1][0,L−1] 求出每个灰度级的概率
Pi=niN,i=0,1,2,...,L−1P_i=\frac{n_i}{N},i=0,1,2,...,L-1Pi​=Nni​​,i=0,1,2,...,L−1
nin_ini​表示灰度级i的像素个数。
假设一个阈值 TTT ,我们用这个阈值把图像分为了两类 C0C_0C0​ ,C1C_1C1​,其中 C0C_0C0​ 由 [0,T][0,T][0,T] 之间的像素组成,C1C_1C1​ 由 [T+1,L−1][T+1,L-1][T+1,L−1] 之间的像素组成。
设 N0N_0N0​ 为小于阈值的像素的个数,N1N_1N1​ 为大于阈值的像素的个数,则有
N=N0+N1N=N_0+N_1N=N0​+N1​
定义图像均值为
u=∑i=0L−1iniN=(∑i=0L−1ini)/NN/N=∑i=0L−1iPiu=\frac{\sum_{i=0}^{L-1}in_i}{N}=\frac{(\sum_{i=0}^{L-1}in_i)/N}{N/N}=\sum_{i=0}^{L-1}iP_iu=N∑i=0L−1​ini​​=N/N(∑i=0L−1​ini​)/N​=i=0∑L−1​iPi​
同理我们可以得到 C0C_0C0​ 和 C1C_1C1​ 的均值 u0u_0u0​ 和 u1u_1u1​
u0=∑i=0TiniN0=∑i=0TiPi∑i=0TPi=∑i=0TiPiw0u_0=\frac{\sum_{i=0}^{T}in_i}{N_0}=\frac{\sum_{i=0}^{T}iP_i}{\sum_{i=0}^{T}P_i}=\frac{\sum_{i=0}^{T}iP_i}{w_0}u0​=N0​∑i=0T​ini​​=∑i=0T​Pi​∑i=0T​iPi​​=w0​∑i=0T​iPi​​
u1=∑i=T+1L−1iniN1=∑i=T+1L−1iPi∑i=T+1L−1Pi=∑i=T+1L−1iPiw1u_1=\frac{\sum_{i=T+1}^{L-1}in_i}{N_1}=\frac{\sum_{i=T+1}^{L-1}iP_i}{\sum_{i=T+1}^{L-1}P_i}=\frac{\sum_{i=T+1}^{L-1}iP_i}{w_1}u1​=N1​∑i=T+1L−1​ini​​=∑i=T+1L−1​Pi​∑i=T+1L−1​iPi​​=w1​∑i=T+1L−1​iPi​​

w0+w1=1w_0+w_1=1w0​+w1​=1

初看定义图像均值的公式是不是感觉有点云里雾里?又是概率的又是 w0w_0w0​ 和 w1w_1w1​ 之类的。但是仔细观察中间步骤,你会发现所谓图像均值 uuu ,其实就是所有像素值之和再除以像素总数。u0u_0u0​ 和 u1u_1u1​也是同理,只是我们换了形式(用概率)表达而已。

由上式我们也可以得到
u=w0u0+w1u1u=w_0u_0+w_1u_1u=w0​u0​+w1​u1​
定义类间方差
δ2=w0(u0−u)2+w1(u1−u)2=w0w1(u0−u1)2\delta ^2=w_0(u_0-u)^2+w_1(u_1-u)^2=w_0w_1(u_0-u_1)^2δ2=w0​(u0​−u)2+w1​(u1​−u)2=w0​w1​(u0​−u1​)2

代入 u=w0u0+w1u1u=w_0u_0+w_1u_1u=w0​u0​+w1​u1​ 以及 w0+w1=1w_0+w_1=1w0​+w1​=1 可推出等式右边。

选取合适的阈值 TTT ,使得类间方差δ2\delta ^2δ2最大,则 TTT 为最佳阈值。

像素值小于这个阈值的像素我们设置为0(黑),否则为1(白)。这样我们就得到了二值化图像。

3. Python代码实现

import cv2
import numpy as np# 大津二值化算法
def otsu(gray_img):h = gray_img.shape[0]w = gray_img.shape[1]N = h * wthreshold_t = 0max_g = 0# 遍历每一个灰度级for t in range(256):# 使用numpy直接对数组进行运算n0 = gray_img[np.where(gray_img < t)]n1 = gray_img[np.where(gray_img >= t)]w0 = len(n0) / Nw1 = len(n1) / Nu0 = np.mean(n0) if len(n0) > 0 else 0.u1 = np.mean(n1) if len(n1) > 0 else 0.g = w0 * w1 * (u0 - u1) ** 2if g > max_g:max_g = gthreshold_t = tprint('类间方差最大阈值:', threshold_t)gray_img[gray_img < threshold_t] = 0gray_img[gray_img >= threshold_t] = 255return gray_img# 读入灰度图
gray_img = cv2.imread('lena.jpg', 0)
otsu_img = otsu(gray_img)
ret, threshold = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print(np.all(otsu_img == threshold))  # ture,说明和opencv底层实现的大津法效果一致
cv2.imshow('otsu_img ', otsu_img)
cv2.imshow("opencv-python otsu_img", threshold)cv2.waitKey(0)
cv2.destroyAllWindows()

参考:

  • 大津二值化算法OTSU的理解
  • 详细及易读懂的 大津法(OTSU)原理 和 比opencv自带更快的算法实现

OTSU算法/大津法/最大类间方差法 python实现相关推荐

  1. OTSU算法(也称最大类间差法,有时也称之为大津算法)

    在图像处理应用中二值化操作是一个很常用的处理方式,例如零器件图片的处理.文本图片和验证码图片中字符的提取.车牌识别中的字符分割,以及视频图像中的运动目标检测中的前景分割,等等. 较为常用的图像二值化方 ...

  2. 图像处理_Ostu算法(大律法、最大类间方差法)

    一.算法简述 Otsu算法是一种用于二值化最佳阈值的选取方法.基本原理是根据阈值T将图像中的像素点分为C1和C2两类,不断的调整阈值T之后若此时两类之间存在最大的类间方差,那么此阈值即是最佳阈值. 二 ...

  3. CUDA精进之路(五):图像处理——OTSU二值算法(最大类间方差法、大津法)

    引言 最近在做医疗设备相关的项目,故在项目中大量用到了各类图像分割的算法,为了在图像中分割出特定目标,用到的算法可以有很多,比如阈值分割,多通道分割,边缘分割以及一些前沿的组合分割.而对大多数图像来说 ...

  4. 图像二值化之最大类间方差法(大津法,OTSU)

    参考文章1:图像二值化与otsu算法介绍 参考文章2:python opencv cv2.threshold() (将固定级别的阈值应用于每个数组元素)ThresholdTypes 最大类间方差法(大 ...

  5. 【机器视觉学习笔记】大津法/Otsu最大类间方差法 最佳阈值处理(C++)

    目录 概念 C++源码 OtsuThreshold 主函数 效果 完整源码 平台:Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文所用源码修改自C+ ...

  6. 最大类间方差法(大津法OTSU)原理

    算法介绍 最大类间方差法是1979年由日本学者大津提出的,是一种自适应阈值确定的方法,又叫大津法,简称OTSU,是一种基于全局的二值化算法,它是根据图像的灰度特性,将图像分为前景和背景两个部分.当取最 ...

  7. 基于OTSU最大类间方差法的ROI分割、提取图像中的形状特征--面积、周长、离心率、zernike矩

    分享一下最近学习的图像分类方面知识,整体的思路如下(之前的汇报ppt里截的) 把这个过程拆分几个部分共同学习一下吧 1.Otsu法原理 最大类间方差法OTSU是一种自适应的全局阈值确定的方法,根据灰度 ...

  8. opencv与C++实现最大类间方差法(OTSU)进行图像二值化

    直接上代码,使用最大类间方差法进行二值化的函数 void threshold_otsu(Mat &mat, Mat &mat_thresh) //mat为输入图像,mat_thresh ...

  9. Ostu最大类间方差法的C++实现

    一.Ostu的原理 最大类间方差法是由日本学者大津(Nobuyuki Ostu)在1979年提出的,该方法根据计算公式自动计算分割单域值,是一种根据灰度图像自动计算阈值的方法.它按照灰度图像的灰度值等 ...

  10. 基于遗传算法的二维最大类间方差法的图像分割优化

    一.背景 最大类间方差阈值分割法日本大津展之在1980年提出的,其基本思路是将图像的直方图以某一灰度为阈值,将图像分成两组并计算两组的方差,当被分成的两组之间的方差最大时,就以这个灰度值为國值分割图像 ...

最新文章

  1. Tensorflow会话
  2. iOS CoreBluetooth 教程
  3. Hadoop入门(二十二)Mapreduce的求平均值程序
  4. html5 定位 计算距离,HTML5 地理定位+地图 API:计算用户到商家的距离
  5. linux vbox安装mac os,超简单的linux下virtualbox4.3.26安装配置黑苹果 OSX 10.9的办法
  6. 【笔记】win10上使用Magic Trackpad2触摸板
  7. [转]《博客园精华集》ASP.NET分册第2论筛选结果文章列表
  8. Microsoft SQL Server 2000的版本区别及选择
  9. 记录一次夏令时和冬令时导致的项目BUG
  10. LeetCode 单调栈练习题归纳总结
  11. win7系统怎么用笔记本做wifi热点(转)
  12. SimpleMemory博客园主题定制美化 配置
  13. 解决报错:OSError: Failed to open file b‘D:\\\xe5\xad\xa6\xe4\xb9\xa0\\scipy-_7cm39vc‘(图文并茂版详细版!!)
  14. Ubuntu 16.04安装安装iBus中文输入法
  15. unable to open debugger port问题解决
  16. AutoCAD二次开发多段线分割、添加顶点
  17. js 分行显示已选爱好
  18. android gridview 行高设置
  19. 知识图谱本体建模工具Protege使用教程
  20. SpringAOP之日志管理

热门文章

  1. 从NC程序中提取路径点的XYZ
  2. MarkDown下载及学习笔记
  3. qnx 镜像文件_QNX OS镜像
  4. PN结的形成及PN结工作原理(单向导电)讲解
  5. cups支持的打印机列表_CUPS共享打印机服务
  6. NDK 开发之 CMake 的使用
  7. mysql 安装版本选择_选择要安装的MySQL版本
  8. win8系统本地计算机策略,win8本地安全策略怎么打开?三种方法轻松打开win8本地安全策略...
  9. 后缀树总结-java版
  10. STM8单片机的多通道连续AD采集