目录

一、简介

二、最大类间方差法(大津法)

2.1 最大类间方差法原理

2.2 基于opencv的实现(简单阈值分割、Otsu阈值分割)

三、自适应阈值分割

参考


一、简介

图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术。它特别适用于目标和背景占据不同灰度级范围的图像。它不仅可以极大的压缩数据量,而且也大大简化了分析和处理步骤,因此在很多情况下,是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。图像阈值化的目的是要按照灰度级,对像素集合进行一个划分,得到的每个子集形成一个与现实景物相对应的区域,各个区域内部具有一致的属性,而相邻区域不具有这种一致属性。这样的划分可以通过从灰度级出发选取一个或多个阈值来实现。

二、最大类间方差法(大津法)

大津法又叫最大类间方差法、最大类间阈值法(OTSU)。它的基本思想是,用一个阈值将图像中的数据分为两类,一类中图像的像素点的灰度均小于这个阈值,另一类中的图像的像素点的灰度均大于或者等于该阈值。如果这两个类中像素点的灰度的方差越大,说明获取到的阈值就是最佳的阈值(方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致两部分差别变小,因此,使类间方差最大的分割意味着错分概率最小)。利用该阈值可以将图像分为前景和背景两个部分,而我们所感兴趣的部分一般为前景。通过上述,我们可以看出,大津法是一种全局阈值法。

大津法计算简单快速,不受图像亮度和对比度的影响。但对图像噪声敏感;只能针对单一目标分割;当目标和背景大小比例悬殊、类间方差函数可能呈现双峰或者多峰,这个时候效果不好。

2.1 最大类间方差法原理

对于图像I(x,y),前景(即目标)和背景的分割阈值记作T,属于前景的像素点数占整幅图像的比例记为ω0,其平均灰度μ0;背景像素点数占整幅图像的比例为ω1,其平均灰度为μ1。图像的总平均灰度记为μ,类间方差记为σ2。

假设图像的背景较暗,并且图像的大小为M×N,图像中像素的灰度值小于阈值T的像素个数记作N0,像素灰度大于阈值T的像素个数记作N1,则有:

将公式(5)代入式(6),得到等价公式为:

上式就是求得的类间方差,再通过遍历,对图片的像素级进行遍历,找到使类间方差最大的阈值T,即为所求的分割阈值。

根据上面的公式,我们可以做进一步的变形:

根据定义我们能够进一步推导μ0和μ1的变形公式如下:

式中,L表示图像灰度级,ni表示灰度为i的像素的数量。

考虑灰度级T的累加均值m(非完全严格定义)和图像的全局均值μ为:

根据公式(10)和(11)可以将公式(8)和(9)改写成:

将公式(12)(13)代入式(7),可得:

2.2 基于opencv的实现(简单阈值分割、Otsu阈值分割)

简单阈值分割

在opencv中可以使用cv2.threshold()函数进行简单阈值分割。

这个函数的第一个参数就是原图像,原图像应该是灰度图。第二个参数就是用来对像素值进行分类的阀值,第三个参数就是当像素值高于(或者小于)阀值时,应该被赋予新的像素值。OpenCV提供了多种不同的阀值方法,这是有第四个参数来决定的。方法包括:

cv2.THRESH_BINARY 二值阈值化

cv2.THRESH_BINARY_INV 反向二值阈值化

cv2.THRESH_TRUNC 截断阈值化

cv2.THRESH_TOZERO 超过阈值归零

cv2.THRESH_TOZERO_INV 低于阈值归零

该方法返回两个输出。第一个是使用的阈值,第二个输出是阈值后的图像

简单阈值分割代码实现:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltimg = cv.imread('gradient.png',0)ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
ret,thresh2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV)
ret,thresh3 = cv.threshold(img,127,255,cv.THRESH_TRUNC)
ret,thresh4 = cv.threshold(img,127,255,cv.THRESH_TOZERO)
ret,thresh5 = cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in xrange(6):plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')plt.title(titles[i])plt.xticks([]),plt.yticks([])
plt.show()

简单阈值分割效果:

Otsu阈值分割

正如上面的实例,在全局阈值化中,我们使用任意选择的值作为阈值。而Otsu的方法避免了必须选择一个值并能够自动确定阈值。在cv2.threshold()函数中因为Otsu’s方法会产生一个阈值,那么函数cv2.threshold的的第二个参数(设置阈值)就是0了,并且在cv2.threshold的方法参数中还得加上语句cv2.THRESH_OTSU。

考虑仅具有两个不同图像值的图像(双峰图像),其中直方图将仅包含两个峰。一个好的阈值应该在这两个值的中间。类似地,Otsu的方法从图像直方图中确定最佳全局阈值。

查看以下示例。输入图像为噪点图像。在第一种情况下,采用值为127的全局阈值。在第二种情况下,直接采用Otsu阈值法。在第三种情况下,首先使用5x5高斯核对图像进行滤波以去除噪声,然后应用Otsu阈值处理。了解噪声滤波如何改善结果。

Otsu阈值分割代码实现:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltimg = cv.imread('noisy2.png',0)# 全局阈值
ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
# Otsu阈值
ret2,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
# 高斯滤波后再采用Otsu阈值
blur = cv.GaussianBlur(img,(5,5),0)
ret3,th3 = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)# 绘制所有图像及其直方图
images = [img, 0, th1,img, 0, th2,blur, 0, th3]
titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)','Original Noisy Image','Histogram',"Otsu's Thresholding",'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]
for i in xrange(3):plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
plt.show()

Otsu阈值分割效果:

三、自适应阈值分割

前面介绍了OTSU算法,但这算法属于全局阈值法,所以对于某些光照不均的图像,这种全局阈值分割的方法会显得苍白无力,如下图情况:

我们可以通过自适应阈值法(adaptiveThreshold)改变这种情况。它的思想不是计算全局图像的阈值,而是根据图像不同区域亮度分布,计算其局部阈值,所以对于图像不同区域,能够自适应计算不同的阈值,因此被称为自适应阈值法(其实就是局部阈值法)。我们可以通过计算某个邻域(局部)的均值、中值、高斯加权平均(高斯滤波)来确定阈值,从而实现自适应阈值分割。值得说明的是:如果用局部的均值作为局部的阈值,就是常说的移动平均法。

在opencv中提供了cv2.adaptiveThreshold()实现自适应阈值分割。

adaptiveThreshold(src: Any,             #源图像maxValue: Any,        #分配给超过阈值的像素值的最大值adaptiveMethod: Any,  #在一个邻域内计算阈值所采用的算法,有两个取值,分别为 ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C thresholdType: Any,   #这是阈值类型,只有两个取值,分别为 THRESH_BINARY 和THRESH_BINARY_INVblockSize: Any,       #adaptiveThreshold的计算单位是像素的邻域块,这是局部邻域大小C: Any,               #这个参数实际上是一个偏移值调整量,用均值和高斯计算阈值后,再减或加这个值就是最终阈值dst: Any = None)      #输出图像

自适应阈值分割代码实现:

import cv2
import matplotlib.pyplot as pltliteracy_path = 'imageData/literacy.jpg'img = cv2.imread(literacy_path, 0)# threshold
ret, thresh = cv2.threshold(img_literacy, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print(ret)  # 124
# adaptive threshold
thresh1 = cv2.adaptiveThreshold(img_literacy, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 0)
thresh2 = cv2.adaptiveThreshold(img_literacy, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
thresh3 = cv2.adaptiveThreshold(img_literacy, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 0)
thresh4 = cv2.adaptiveThreshold(img_literacy, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)# show image
plt.figure('adaptive threshold', figsize=(12, 8))
plt.subplot(231), plt.imshow(img_literacy, cmap='gray'), plt.title('original')
plt.subplot(234), plt.imshow(thresh, cmap='gray'), plt.title('otsu')
plt.subplot(232), plt.imshow(thresh1, cmap='gray'), plt.title('adaptive_mean_0')
plt.subplot(235), plt.imshow(thresh2, cmap='gray'), plt.title('adaptive_mean_2')
plt.subplot(233), plt.imshow(thresh3, cmap='gray'), plt.title('adaptive_gaussian_0')
plt.subplot(236), plt.imshow(thresh4, cmap='gray'), plt.title('adaptive_gaussian_2')
plt.show()

自适应阈值分割效果:

参考

http://www.woshicver.com/FifthSection/4_3_%E5%9B%BE%E5%83%8F%E9%98%88%E5%80%BC/

https://www.kancloud.cn/aollo/aolloopencv/267591

自适应阈值(adaptiveThreshold)分割原理及实现

CV笔记5:图像分割之最大类间方差法、自适应阈值分割(基于python-opencv实现)相关推荐

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

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

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

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

  3. K210 / Openmv实现 大津法/Otsu最大类间方差法 自适应二值化

    目录 源码 效果 平台:K210 固件版本:maixpy_v0.6.2_54_g897214100_openmv_kmodel_v4_with_ide_support.bin OpenMv库自带Ots ...

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

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

  5. 数字图像处理实验(六)|图像分割{阈值分割、直方图法、OTUS最大类间方差法(edge、im2dw、imfilter、imresize)、迭代阈值法、点检测}(附matlab实验代码和截图)

    文章目录 一.实验目的 二.实验原理 (一) 阈值分割 1. 直方图法 2.OTSU法(最大类间方差法)确定阈值 3. 迭代阈值法 4. 点检测 (二)边缘检测 三.实验内容 (一)阈值分割 1. 直 ...

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

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

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

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

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

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

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

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

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

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

最新文章

  1. LiTAMIN2:一种超轻型LiDAR-SLAM(ICRA2021)
  2. JDK8安装及设置环境变量
  3. AVPlayer支持VSFilter啦, 也就支持字幕啦
  4. ARM 之十 ARMCC(Keil) map 文件(映射文件)详解
  5. OpenGL缩放转换
  6. 304 Not Modify
  7. 牛客 - 拿物品(贪心)
  8. Linux 图片传输功能c/c++(初版)
  9. java 捆绑_java – 如何在jar文件中捆绑图像
  10. Canvas渲染会取代DOM吗?
  11. 开启 C++ 生活 -- 第一个 C++ 程序
  12. Java- Math类
  13. logistic回归详解(四):梯度下降训练逻辑回归python实现
  14. 腾讯云TCP架构高级工程师认证考试大纲、考题下载及说明
  15. 微信小程序添加插屏广告并设置显示频率(一天一次)
  16. 笔记本 原因代码: 0x500ff 关机类型: 关闭电源_关于笔记本电池更换的建议
  17. Elasticsearch(ES)的基本使用
  18. mysql applier_新特性解读 | MySQL 8.0.18 有权限控制的复制
  19. 身体质量指数BMI——python
  20. 使用 PoseNet 和实时深度学习项目进行姿势检测

热门文章

  1. addr2line工具使用
  2. 字节游戏测试开发面试题
  3. VS2019安装和使用教程
  4. Charles 手机https抓包
  5. 微信统一服务(小程序服务通知与微信公众号模板消息)发送
  6. HTML5基础学习(6):个人简历制作
  7. 华为PUSH推送所有Token都不合法
  8. Homography和warpPerspective
  9. navicat for mysql Mac版 中文免安装
  10. MATLAB零基础入门教程视频课程