图像二值化(Image Binarization):平均值法、双峰法、大津算法(OTSU)_大津法-程序员宅基地

技术标签: 计算机视觉(CV方向)  计算机视觉  二值化  数字图像处理  

图像二值化(Image Binarization):平均值法、双峰法、大津算法(OTSU)

编程实现图像的二值化,分析不同的阈值对二值化图像的影响。

问题描述

传统的机器视觉通常包括两个步骤:预处理和物体检测。而沟通二者的桥梁则是图像分割(Image Segmentation)。图像分割通过简化或改变图像的表示形式,使得图像更易于分析。最简单的图像分割方法是二值化(Binarization)。

图像二值化(Image Binarization)就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。二值图像每个像素只有两种取值:要么纯黑,要么纯白。

由于二值图像数据足够简单,许多视觉算法都依赖二值图像。通过二值图像,能更好地分析物体的形状和轮廓。二值图像也常常用作原始图像的掩模(又称遮罩、蒙版,Mask):它就像一张部分镂空的纸,把我们不感兴趣的区域遮掉。进行二值化有多种方式,其中最常用的就是采用阈值法(Thresholding)进行二值化。其将大于某个临界灰度值的像素灰度设为灰度极大值,小于这个值的为灰度极小值,从而实现二值化。

阈值法又分为全局阈值(Global Method)和局部阈值(Local Method),又称自适应阈值(Adaptive Thresholding)。本次实验主要实现全局阈值,阈值的选取基于以下三种方法:

  • 平均值法
  • 双峰法
  • OTSU法

平均值法

为了应对每张图片的灰度值大不相同,阈值取为图像本身的平均值.

import cv2
import numpy as np
import matplotlib.pyplot as plt

img_name0 = 'lena_gray.bmp'
img0 = cv2.imread(img_name0)

plt.imshow(img0)
plt.show()

在这里插入图片描述

def mean_binarization(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    threshold = np.mean(img_gray)
    img_gray[img_gray>threshold] = 255
    img_gray[img_gray<=threshold] = 0
    # For displaying a grayscale image set up the colormapping using the parameters cmap='gray', vmin=0, vmax=255.
    plt.imshow(img_gray, cmap='gray')
    plt.show()
    return img_gray

img_gray0 = mean_binarization(img0)

在这里插入图片描述

双峰法

如果物体与背景的灰度值对比明显,直方图就会包含双峰(bimodal histogram),它们分别为图像的前景和背景。而它们之间的谷底即为边缘附近相对较少数目的像素点,一般来讲,这个最小值就为最优二值化的分界点,通过这个点可以把前景和背景很好地分开。

from collections import Counter

def hist_binarization(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    hist = img_gray.flatten()
    plt.subplot(121)
    plt.hist(hist, 256)
    cnt_hist = Counter(hist)
    most_commons = cnt_hist.most_common(2)
    # get the grey values of bimodal histogram
    begin, end = most_commons[0][0], most_commons[1][0]
    if begin > end:
        begin, end = end, begin
    print(f'{
      begin}: {
      end}')

    cnt = np.iinfo(np.int16).max
    threshold = 0
    for i in range(begin, end+1):
        if cnt_hist[i] < cnt:
            cnt = cnt_hist[i]
            threshold = i
    print(f'{
      threshold}: {
      cnt}')
    img_gray[img_gray>threshold] = 255
    img_gray[img_gray<=threshold] = 0
    plt.subplot(122)
    plt.imshow(img_gray, cmap='gray')
    plt.show()
    return img_gray

img_gray1 = hist_binarization(img0)

在这里插入图片描述

上述直方图两峰值没有间距,故未能较好体现双峰法的作用.

OTSU法

不难发现,上述双峰法具有明显的缺陷,因为直方图是不连续的,有非常多尖峰和抖动,要找到准确的极值点十分困难。日本工程师大津展之为这个波谷找到了一个合适的数学表达,并于1979年发表。这个二值化方法称为大津算法(Otsu’s method)。

从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。它被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用。它是按图像的灰度特性,将图像分成背景和前景两部分。因方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致类间差别变小。因此,使类间方差最大的分割意味着错分概率最小。

优化目标

k ∗ = arg ⁡ max ⁡ k ∈ L σ 2 k^* = \mathop { \arg \max } \limits _{k\in L} \sigma ^2 k=kLargmaxσ2

σ 2 = ( M G ∗ p 1 − m ) 2 p 1 ( 1 − p 1 ) \sigma ^2 = \frac{(MG*p1-m)^2}{p1(1-p1)} σ2=p1(1p1)(MGp1m)2

推导

https://blog.csdn.net/m0_54351828/article/details/120642025

由所选定的阈值 k k k 将所有像素分为两类 C1( 小于等于 k k k ) 和 C2(大于 k k k ),两类像素的均值分别为 m 1 m1 m1 m 2 m2 m2,全局均值为 M G MG MG.属于 C1、C2 的概率分别为 p 1 p1 p1 p 2 p2 p2. L 是图像的像素级(0~255)

根据方差定义,得到

σ 2 = p 1 ( m 1 − M G ) 2 + p 2 ( m 2 − M G ) 2 \sigma ^2 = p1(m1-MG)^2 + p2(m2-MG)^2 σ2=p1(m1MG)2+p2(m2MG)2

p 1 ∗ m 1 + p 2 ∗ m 2 = M G p1*m1+p2*m2=MG p1m1+p2m2=MG

p 1 + p 2 = 1 p1+p2=1 p1+p2=1

其中,

p 1 = ∑ i = 0 k p i p1=\sum _{i=0} ^k p_i p1=i=0kpi

m 1 = ∑ i = 0 k i p i p 1 m1 = \frac{\sum _{i=0} ^k ip_i}{p1} m1=p1i=0kipi

m 2 = ∑ i = k + 1 L i p i p 2 m2 = \frac{\sum _{i=k+1} ^L ip_i}{p2} m2=p2i=k+1Lipi

p i p_i pi 是灰度值为 i 的像素点出现的频率(或概率)

σ 2 = p 1 p 2 ( m 1 − m 2 ) 2 \sigma ^2 = p1p2(m1-m2)^2 σ2=p1p2(m1m2)2.

进一步化简上式,

M G = ∑ i = 0 L i p i MG=\sum _{i=0} ^{L} ip_i MG=i=0Lipi

m = ∑ i = 0 k i p i m=\sum _{i=0} ^{k} ip_i m=i=0kipi

其中, m m m 是灰度阈值 k k k 的累加均值(相对整张图片而言的均值,而 m1 是 C1 类的类内均值), M G MG MG 是全局均值,和前文所述一致,则

m 1 = m p 1 m1=\frac{m}{p1} m1=p1m

m 2 = M G − m p 2 m2=\frac{MG-m}{p2} m2=p2MGm

由此可的最终的类间方差公式:

σ 2 = ( M G ∗ p 1 − m ) 2 p 1 ( 1 − p 1 ) \sigma ^2 = \frac{(MG*p1-m)^2}{p1(1-p1)} σ2=p1(1p1)(MGp1m)2

def otsu(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    h, w = img_gray.shape[:2]
    pixel = h * w
    threshold_k = 0
    max_var = .0

    for k in range(255):
        c1 = img_gray[img_gray <= k]

        p1 = len(c1) / pixel
        if p1 == 0:
            continue
        elif p1 == 1:
            break

        MG = np.sum(img_gray) / pixel

        m = np.sum(c1) / pixel

        d = (MG*p1 - m) ** 2 / (p1 * (1 - p1))
        if d > max_var:
            max_var = d
            threshold_k = k

    img_gray[img_gray <= threshold_k] = 0
    img_gray[img_gray > threshold_k] = 255

    print(f"{
      threshold_k}")
    plt.imshow(img_gray, cmap='gray')
    plt.show()
    return img_gray

img_gray2 = otsu(img0)

在这里插入图片描述

结果分析

OTSU算法得到的阈值产生了比上述两者都好的分割效果,其按图像的灰度特性,将Lena分成背景和前景两部分,接着遍历阈值,找到使得前景、背景二类间方差最大的阈值,作为二值化的阈值.

Sylvan Ding 转载注明出处!

参考文献

  1. Otsu大津算法公式推导及python实现
  2. OTSU算法(大津法—最大类间方差法)原理及实现
  3. 二值化_初探图像二值化
  4. 一文搞懂图像二值化算法
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/IYXUAN/article/details/124458001

智能推荐

从零开始搭建Hadoop_创建一个hadoop项目-程序员宅基地

文章浏览阅读331次。第一部分:准备工作1 安装虚拟机2 安装centos73 安装JDK以上三步是准备工作,至此已经完成一台已安装JDK的主机第二部分:准备3台虚拟机以下所有工作最好都在root权限下操作1 克隆上面已经有一台虚拟机了,现在对master进行克隆,克隆出另外2台子机;1.1 进行克隆21.2 下一步1.3 下一步1.4 下一步1.5 根据子机需要,命名和安装路径1.6 ..._创建一个hadoop项目

心脏滴血漏洞HeartBleed CVE-2014-0160深入代码层面的分析_heartbleed代码分析-程序员宅基地

文章浏览阅读1.7k次。心脏滴血漏洞HeartBleed CVE-2014-0160 是由heartbeat功能引入的,本文从深入码层面的分析该漏洞产生的原因_heartbleed代码分析

java读取ofd文档内容_ofd电子文档内容分析工具(分析文档、签章和证书)-程序员宅基地

文章浏览阅读1.4k次。前言ofd是国家文档标准,其对标的文档格式是pdf。ofd文档是容器格式文件,ofd其实就是压缩包。将ofd文件后缀改为.zip,解压后可看到文件包含的内容。ofd文件分析工具下载:点我下载。ofd文件解压后,可以看到如下内容: 对于xml文件,可以用文本工具查看。但是对于印章文件(Seal.esl)、签名文件(SignedValue.dat)就无法查看其内容了。本人开发一款ofd内容查看器,..._signedvalue.dat

基于FPGA的数据采集系统(一)_基于fpga的信息采集-程序员宅基地

文章浏览阅读1.8w次,点赞29次,收藏313次。整体系统设计本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下:图1:FPGA数据采集系统框图从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D.._基于fpga的信息采集

微服务 spring cloud zuul com.netflix.zuul.exception.ZuulException GENERAL-程序员宅基地

文章浏览阅读2.5w次。1.背景错误信息:-- [http-nio-9904-exec-5] o.s.c.n.z.filters.post.SendErrorFilter : Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud..._com.netflix.zuul.exception.zuulexception

邻接矩阵-建立图-程序员宅基地

文章浏览阅读358次。1.介绍图的相关概念  图是由顶点的有穷非空集和一个描述顶点之间关系-边(或者弧)的集合组成。通常,图中的数据元素被称为顶点,顶点间的关系用边表示,图通常用字母G表示,图的顶点通常用字母V表示,所以图可以定义为:  G=(V,E)其中,V(G)是图中顶点的有穷非空集合,E(G)是V(G)中顶点的边的有穷集合1.1 无向图:图中任意两个顶点构成的边是没有方向的1.2 有向图:图中..._给定一个邻接矩阵未必能够造出一个图

随便推点

MDT2012部署系列之11 WDS安装与配置-程序员宅基地

文章浏览阅读321次。(十二)、WDS服务器安装通过前面的测试我们会发现,每次安装的时候需要加域光盘映像,这是一个比较麻烦的事情,试想一个上万个的公司,你天天带着一个光盘与光驱去给别人装系统,这将是一个多么痛苦的事情啊,有什么方法可以解决这个问题了?答案是肯定的,下面我们就来简单说一下。WDS服务器,它是Windows自带的一个免费的基于系统本身角色的一个功能,它主要提供一种简单、安全的通过网络快速、远程将Window..._doc server2012上通过wds+mdt无人值守部署win11系统.doc

python--xlrd/xlwt/xlutils_xlutils模块可以读xlsx吗-程序员宅基地

文章浏览阅读219次。python–xlrd/xlwt/xlutilsxlrd只能读取,不能改,支持 xlsx和xls 格式xlwt只能改,不能读xlwt只能保存为.xls格式xlutils能将xlrd.Book转为xlwt.Workbook,从而得以在现有xls的基础上修改数据,并创建一个新的xls,实现修改xlrd打开文件import xlrdexcel=xlrd.open_workbook('E:/test.xlsx') 返回值为xlrd.book.Book对象,不能修改获取sheett_xlutils模块可以读xlsx吗

关于新版本selenium定位元素报错:‘WebDriver‘ object has no attribute ‘find_element_by_id‘等问题_unresolved attribute reference 'find_element_by_id-程序员宅基地

文章浏览阅读8.2w次,点赞267次,收藏656次。运行Selenium出现'WebDriver' object has no attribute 'find_element_by_id'或AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath'等定位元素代码错误,是因为selenium更新到了新的版本,以前的一些语法经过改动。..............._unresolved attribute reference 'find_element_by_id' for class 'webdriver

DOM对象转换成jQuery对象转换与子页面获取父页面DOM对象-程序员宅基地

文章浏览阅读198次。一:模态窗口//父页面JSwindow.showModalDialog(ifrmehref, window, 'dialogWidth:550px;dialogHeight:150px;help:no;resizable:no;status:no');//子页面获取父页面DOM对象//window.showModalDialog的DOM对象var v=parentWin..._jquery获取父window下的dom对象

什么是算法?-程序员宅基地

文章浏览阅读1.7w次,点赞15次,收藏129次。算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵 魂。二、算法的特征1.可行性 算法中执行的任何计算步骤都可以分解为基本可执行的操作步,即每个计算步都可以在有限时间里完成(也称之为有效性) 算法的每一步都要有确切的意义,不能有二义性。例如“增加x的值”,并没有说增加多少,计算机就无法执行明确的运算。 _算法

【网络安全】网络安全的标准和规范_网络安全标准规范-程序员宅基地

文章浏览阅读1.5k次,点赞18次,收藏26次。网络安全的标准和规范是网络安全领域的重要组成部分。它们为网络安全提供了技术依据,规定了网络安全的技术要求和操作方式,帮助我们构建安全的网络环境。下面,我们将详细介绍一些主要的网络安全标准和规范,以及它们在实际操作中的应用。_网络安全标准规范

推荐文章

热门文章

相关标签