当前位置: 首页 > news >正文

OpenCV 对图像进行阈值处理 cv2.threshold

OpenCV 对图像进行阈值处理 cv2.threshold

flyfish

二值化的含义

基本概念

在图像处理领域,二值化是一种非常基础且重要的操作。它的核心目的是将图像中的像素值简化为两种状态,通常用 0 和 255 来表示,分别对应黑色和白色。简单来说,二值化就是把一幅灰度图像转换为只有黑和白两种颜色的图像。

实现原理

二值化处理主要依据设定的阈值来完成。对于图像中的每个像素,如果其灰度值大于设定的阈值,就将该像素的值设为一个特定的最大值(通常是 255,表示白色);如果灰度值小于或等于阈值,就将其设为 0(表示黑色)。其数学表达式如下:
f ( x , y ) = { 255 , if  g ( x , y ) > T 0 , if  g ( x , y ) ≤ T f(x,y) = \begin{cases} 255, & \text{if } g(x,y) > T \\ 0, & \text{if } g(x,y) \leq T \end{cases} f(x,y)={255,0,if g(x,y)>Tif g(x,y)T
这里的 (f(x,y)) 是二值化后图像在 ((x,y)) 位置的像素值,(g(x,y)) 是原始图像在 ((x,y)) 位置的像素值,(T) 则是设定的阈值。

应用场景

二值化在很多实际场景中都有广泛应用,例如:

  • 文字识别:将文字图像二值化后,可以更清晰地分离出文字和背景,有助于后续的字符分割和识别。
  • 目标检测:二值化能突出目标物体,方便检测和定位目标。
  • 图像分析:简化图像信息,降低处理复杂度,使后续的分析更加高效。

cv2.threshold 函数

功能概述

cv2.threshold 函数用于对图像进行阈值处理。阈值处理是一种简单的图像分割方法,它将图像中的像素值根据设定的阈值进行分类,将像素值大于阈值的像素设置为一个值(通常是 255,表示白色),将像素值小于等于阈值的像素设置为另一个值(通常是 0,表示黑色)。

函数语法
ret, binary = cv2.threshold(src, thresh, maxval, type)
  • 参数说明
    • src:输入的单通道图像,通常是灰度图像。
    • thresh:设定的阈值。在使用 Otsu 方法时,这个参数会被忽略,因为 Otsu 方法会自动计算出最优的阈值。
    • maxval:当像素值大于阈值时,将其设置为这个值,通常为 255。
    • type:阈值处理的类型,常见的类型有:
      • cv2.THRESH_BINARY:二值化阈值处理,像素值大于阈值的设为 maxval,小于等于阈值的设为 0。
      • cv2.THRESH_BINARY_INV:反向二值化阈值处理,像素值大于阈值的设为 0,小于等于阈值的设为 maxval
      • cv2.THRESH_OTSU:Otsu 方法,它会自动计算出一个最优的阈值,该方法通常与其他阈值处理类型结合使用,如 cv2.THRESH_BINARY + cv2.THRESH_OTSU
  • 返回值
    • ret:返回的阈值,如果使用了 Otsu 方法,这个值就是 Otsu 计算出的最优阈值。
    • binary:阈值处理后的二值图像。

Otsu 方法,也被称为大津法,是由日本学者大津展之在 1979 年提出的一种自动确定图像二值化阈值的算法。在进行图像二值化时,关键在于选择合适的阈值,而 Otsu 方法能够自动找到一个最优的阈值,使得分割后的图像类间方差最大。以下为你详细介绍:

基本原理

Otsu 方法的核心思想是将图像中的像素分为两类(前景和背景),通过遍历所有可能的阈值,计算每一个阈值下这两类像素的类间方差,选择使类间方差达到最大值的阈值作为最优阈值。类间方差反映了这两类像素的差异程度,类间方差越大,说明这两类像素的区分度越高,分割效果也就越好。

算法步骤

假设图像的灰度级范围是 [ 0 , L − 1 ] [0, L - 1] [0,L1],具体步骤如下:

  1. 计算灰度直方图:统计图像中每个灰度级的像素数量,得到灰度直方图。
  2. 遍历所有可能的阈值:从 t = 0 t = 0 t=0 t = L − 1 t = L - 1 t=L1 遍历所有可能的阈值。
  3. 计算每一个阈值下的相关参数
    • 计算背景像素的概率 w 0 ( t ) w_0(t) w0(t) 和前景像素的概率 w 1 ( t ) w_1(t) w1(t)
      w 0 ( t ) = ∑ i = 0 t p ( i ) w_0(t)=\sum_{i = 0}^{t}p(i) w0(t)=i=0tp(i)
      w 1 ( t ) = ∑ i = t + 1 L − 1 p ( i ) = 1 − w 0 ( t ) w_1(t)=\sum_{i = t+1}^{L - 1}p(i)=1 - w_0(t) w1(t)=i=t+1L1p(i)=1w0(t)
      其中, p ( i ) p(i) p(i) 是灰度级为 i i i 的像素出现的概率。
    • 计算背景像素的平均灰度值 μ 0 ( t ) \mu_0(t) μ0(t) 和前景像素的平均灰度值 μ 1 ( t ) \mu_1(t) μ1(t)
      μ 0 ( t ) = 1 w 0 ( t ) ∑ i = 0 t i × p ( i ) \mu_0(t)=\frac{1}{w_0(t)}\sum_{i = 0}^{t}i\times p(i) μ0(t)=w0(t)1i=0ti×p(i)
      μ 1 ( t ) = 1 w 1 ( t ) ∑ i = t + 1 L − 1 i × p ( i ) \mu_1(t)=\frac{1}{w_1(t)}\sum_{i = t + 1}^{L - 1}i\times p(i) μ1(t)=w1(t)1i=t+1L1i×p(i)
    • 计算类间方差 σ B 2 ( t ) \sigma_B^2(t) σB2(t)
      σ B 2 ( t ) = w 0 ( t ) w 1 ( t ) ( μ 0 ( t ) − μ 1 ( t ) ) 2 \sigma_B^2(t)=w_0(t)w_1(t)(\mu_0(t)-\mu_1(t))^2 σB2(t)=w0(t)w1(t)(μ0(t)μ1(t))2
  4. 选择最优阈值:找到使类间方差 σ B 2 ( t ) \sigma_B^2(t) σB2(t) 最大的阈值 t ∗ t^* t,即:
    t ∗ = arg ⁡ max ⁡ 0 ≤ t ≤ L − 1 σ B 2 ( t ) t^*=\arg\max_{0\leq t\leq L - 1}\sigma_B^2(t) t=arg0tL1maxσB2(t)

代码示例

import cv2# 读取图像,以灰度模式读取
image = cv2.imread('example.jpg', 0)# 使用 Otsu 方法进行二值化处理
ret, binary = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 显示原始图像
cv2.imshow('Original Image', image)# 显示二值化后的图像
cv2.imshow('Otsu Binary Image', binary)# 等待按键事件,按任意键关闭窗口
cv2.waitKey(0)# 关闭所有打开的窗口
cv2.destroyAllWindows()

解释

  • cv2.imread('example.jpg', 0):以灰度模式读取图像。
  • cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU):使用 Otsu 方法进行二值化处理,0 这个参数会被 Otsu 方法忽略,255 是像素值大于阈值时设置的值。
  • ret:返回的最优阈值。
  • binary:二值化后的图像。

优缺点

  • 优点
    • 无需人为设定阈值,自动计算最优阈值,使用方便。
    • 计算速度较快,适用于实时处理。
  • 缺点
    • 假设图像的灰度分布是双峰的,对于灰度分布不符合双峰特征的图像,分割效果可能不理想。
    • 对噪声比较敏感,噪声可能会影响阈值的选择。

相关文章:

  • 【Rust 精进之路之第11篇-借用·实践】切片 (Slices):安全、高效地引用集合的一部分
  • Opencv图像处理:轮廓检测、轮廓近似、绘制外接圆外接矩形
  • 嵌入式学习——opencv图像库编程
  • puzzle(0531)脑力航迹
  • 33-公交车司机管理系统
  • [ABAQUS有限元分析] 1.单个零件静力学分析
  • Nginx在微服务架构项目(Spring Cloud)中的强大作用
  • 30元一公斤的樱桃甜不甜
  • 《Operating System Concepts》阅读笔记:p748-p748
  • MySQL:9.表的内连和外连
  • 山东大学创新项目实训开发日志(19)之前端知识深度学习
  • 2-6-1-1 QNX编程入门之进程和线程(八)
  • 二叉树的顺序结构及实现
  • 【Flutter】使用LiveKit和Flutter构建实时视频聊天应用
  • 【Docker项目实战】使用Docker部署Jupyter Notebook服务
  • Spring 微服务解决了单体架构的哪些痛点?
  • 深度解析 PointNet:点云深度学习的开山之作
  • 从零开始用Pytorch实现LLaMA 4的混合专家(MoE)模型
  • 【C++详解】C++入门(一)
  • Spring Boot 集成 Spring Cloud 的详细教程
  • 发布近百条《原神》涉密游戏内容,游戏资讯网站被判赔33万元
  • 分离19年后:陈杨梅首度露面,父亲亲手喂棉花糖给女儿吃
  • 南部战区海军新闻发言人发表谈话
  • 新华社经济随笔:把握不确定性中的确定性
  • 报告:去年物业服务百强企业营业收入均值同比增长3.52%
  • 杜甫、韦应物背后的世家大族,在这个展览上一览传奇