opencv之阈值处理

2024-09-01 06:44
文章标签 opencv 阈值 处理

本文主要是介绍opencv之阈值处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1. 阈值处理
  • 2. 阈值处理的基本原理
  • 3. 常见的阈值处理方法
    • 3.1 全局阈值(Global Thresholding):
    • 3.2 自适应阈值(Adaptive Thresholding):
      • 3.2.1 工作原理
      • 3.2.2 工作步骤
      • 3.2.3 适用场景
      • 3.2.4 优缺点
        • 自适应阈值的优点
        • 自适应阈值的缺点
    • 3.3 Otsu’s 方法:
      • 什么是最大化类间方差
      • 工作原理
      • 适用场景
      • 优缺点
  • 4. 应用场景
  • 总结

1. 阈值处理

在图像处理领域,阈值处理(Thresholding)是一种简单而有效的技术,用于将灰度图像转化为二值图像(即每个像素点要么是黑色,要么是白色)。这种处理方式常用于分割图像中的前景和背景,或者提取特定的形状或物体。

2. 阈值处理的基本原理

阈值处理的基本思想是设定一个阈值 T T T,然后遍历图像中的每一个像素。如果像素的灰度值高于阈值,就将其设为白色(通常为255);如果低于阈值,则将其设为黑色(通常为0)。公式如下:

g ( x , y ) = { 255 , i f f ( x , y ) > T 0 , i f f ( x , y ) ≤ T (1) g(x,y)= \begin{cases} 255,if\quad f(x,y)>T\\ 0, if\quad f(x,y)\leq T \end{cases} \tag{1} g(x,y)={255,iff(x,y)>T0,iff(x,y)T(1)
其中, f ( x , y ) f(x,y) f(x,y) 是原始图像的灰度值, g ( x , y ) g(x,y) g(x,y) 是处理后的二值图像。

3. 常见的阈值处理方法

3.1 全局阈值(Global Thresholding):

  • 在这种方法中,整个图像使用同一个阈值。适合于图像对比度较高且背景简单的情况。OpenCV 中常用的函数是 cv2.threshold
import cv2# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 全局阈值处理
_, thresh_global = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)# 显示结果
cv2.imshow('Global Thresholding', thresh_global)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.2 自适应阈值(Adaptive Thresholding):

自适应阈值方法会根据图像的局部区域动态计算阈值,因此对于光照不均或对比度较低的图像更有效。自适应阈值根据局部窗口内的像素值计算每个像素的阈值,从而避免了全局阈值对整个图像的统一处理。

3.2.1 工作原理

自适应阈值(Adaptive Thresholding)的工作原理是根据图像局部区域的特征来动态调整阈值,从而处理光照不均或对比度不够的图像。它的主要思想是对于图像中的每一个像素,根据其周围邻域的像素值来确定一个局部阈值。这样可以避免全局阈值方法可能带来的效果不佳的问题,尤其是在图像的不同区域光照差异较大的情况下。

  • 计算临近区域的加权平均值:

对于图像中的每一个像素点,自适应阈值方法会考虑该像素点周围的一定范围内的像素值。这些像素值形成了一个局部区域或窗口。
通过计算这个局部区域内的像素值的加权平均(或均值),得到一个阈值。加权平均意味着某些像素对计算结果的影响比其他像素更大,通常是窗口中心的像素权重更高。

  • 获得阈值:

计算出的加权平均值(或均值)被用作该像素点的局部阈值。这个阈值代表了该像素所在局部区域的“亮度”水平。

  • 对当前像素点进行处理:

使用计算得到的局部阈值来决定该像素点的类别。具体地说:
如果当前像素的值大于或等于局部阈值,则将其分类为前景(通常设为 255,白色)。
如果当前像素的值小于局部阈值,则将其分类为背景(通常设为 0,黑色)。

3.2.2 工作步骤

1. 局部邻域计算:

  • 将图像划分为多个小的局部区域(通常称为窗口或块),在每个局部区域内计算一个局部阈值。这个局部阈值基于该区域内的像素值来动态确定。

2. 局部阈值计算:

对于每个局部区域,计算其局部阈值的常用方法包括均值和高斯加权平均:

  • 均值自适应阈值(Adaptive Mean Thresholding): 阈值等于邻域像素的平均值减去一个常量。公式如下:

    • 公式: T ( x , y ) = m e a n ( I ( x , y ) ) − C T(x,y)=mean(I(x,y))−C T(x,y)=mean(I(x,y))C

    • 其中:

      • T ( x , y ) T(x,y) T(x,y)是位置 ( x , y ) (x,y) (x,y) 的阈值。
      • m e a n ( I ( x , y ) ) mean(I(x,y)) mean(I(x,y)) 是位置 ( x , y ) (x,y) (x,y) 的邻域内像素的平均值。
      • C C C 是一个常数,用于调整阈值。

​ 在这种方法中,阈值是由邻域内像素的均值减去一个常数 C C C计算得到的。常数 C C C用于避免噪声对分割结果的影响。

  • 高斯自适应阈值(Adaptive Gaussian Thresholding): 阈值等于邻域像素的加权平均值(权重为高斯窗口)减去一个常量。公式如下:

    • T ( x , y ) = m e a n ( I ( x , y ) ) − C ⋅ s t d ( I ( x , y ) ) T(x,y)=mean(I(x,y))−C⋅std(I(x,y)) T(x,y)=mean(I(x,y))Cstd(I(x,y))
    • 其中:
      • T ( x , y ) T(x,y) T(x,y) 是位置 ( x , y ) (x,y) (x,y) 的阈值。
      • m e a n ( I ( x , y ) ) mean(I(x,y)) mean(I(x,y)) 是位置 ( x , y ) (x,y) (x,y)的邻域内像素的平均值。
      • s t d ( I ( x , y ) ) std(I(x,y)) std(I(x,y)) 是位置 ( x , y ) (x,y) (x,y)的邻域内像素的标准差。
      • C C C是一个常数,用于调整阈值。

    在这种方法中,阈值是由邻域内像素的均值减去标准差的 C C C倍计算得到的。这样可以更好地处理局部的光照变化和噪声。

3.二值化处理:

  • 对于每个像素点,将其灰度值与计算得到的局部阈值进行比较。如果灰度值大于局部阈值,则将其设置为白色;否则,设置为黑色。

3.2.3 适用场景

  • 图像光照不均匀或有明显的阴影。
  • 需要在复杂背景下进行分割。

3.2.4 优缺点

自适应阈值的优点
  • 适应光照变化: 能够处理光照不均匀的图像,避免全局阈值方法对不同区域处理不一致的问题。
  • 局部处理: 通过局部窗口计算阈值,可以更好地处理细节和复杂背景。
自适应阈值的缺点
  • 计算复杂度较高: 由于需要对每个像素计算局部阈值,处理时间相对较长。
  • 参数选择: 自适应阈值方法中的参数(如窗口大小和常量)需要根据具体图像调整,以获得最佳效果。
import cv2# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 自适应均值阈值处理
thresh_mean = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY, 11, 2)# 自适应高斯阈值处理
thresh_gaussian = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY, 11, 2)# 显示结果
cv2.imshow('Adaptive Mean Thresholding', thresh_mean)
cv2.imshow('Adaptive Gaussian Thresholding', thresh_gaussian)
cv2.waitKey(0)
cv2.destroyAllWindows()

自定义实现(不使用 OpenCV)

如果你需要从头开始实现自适应阈值处理,以下是一个简化的 Python 代码示例:

import numpy as np
import cv2def adaptive_threshold(image, block_size, C):rows, cols = image.shapepadded_image = np.pad(image, pad_width=block_size//2, mode='constant', constant_values=0)result = np.zeros_like(image)for i in range(rows):for j in range(cols):block = padded_image[i:i+block_size, j:j+block_size]mean = np.mean(block)threshold = mean - Cresult[i, j] = 255 if image[i, j] >= threshold else 0return result# 读取图像(以灰度模式)
image = cv2.imread('input_image.png', cv2.IMREAD_GRAYSCALE)# 设置自适应阈值参数
block_size = 11
constant = 2# 计算自适应阈值
adaptive_thresh = adaptive_threshold(image, block_size, constant)# 显示结果
cv2.imshow('Original Image', image)
cv2.imshow('Adaptive Threshold', adaptive_thresh)# 等待按键并销毁窗口
cv2.waitKey(0)
cv2.destroyAllWindows()# 保存处理后的图像(可选)
cv2.imwrite('adaptive_thresh_custom.png', adaptive_thresh)

3.3 Otsu’s 方法:

Otsu’s 阈值法是一种自动选择阈值的全局方法。它通过分析图像的灰度直方图,找到能够最大化类间方差(前景和背景)的阈值。Otsu’s 方法适用于双峰分布的图像(即前景和背景的灰度值分布相对独立且存在两个峰值)。

什么是最大化类间方差

最大化类间方差(Between-Class Variance)是 Otsu’s 阈值法的核心概念,旨在选择一个最佳阈值,使得图像的前景和背景之间的差异最大化。这种方法通过分析图像的灰度直方图,找到一个阈值,使得图像被分割成前景和背景后,它们之间的类间方差最大。

工作原理

Otsu’s 方法遍历所有可能的阈值,并计算每个阈值对应的类间方差,选择使类间方差最大的阈值作为最终的阈值。

适用场景

  • 图像的灰度直方图呈现双峰分布。
  • 需要自动选择最优阈值。

优缺点

  • 优点: 自动选择阈值,适用于双峰图像的分割。
  • 缺点: 对多峰分布的图像效果不佳,计算量相对较大。

公式推导链接:https://blog.csdn.net/leonardohaig/article/details/120269341

OpenCV 中可以通过设置 cv2.THRESH_OTSU 来使用。

import cv2# 读取灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# Otsu's 阈值处理
_, thresh_otsu = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 显示结果
cv2.imshow('Otsu Thresholding', thresh_otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码

import cv2
import numpy as np# 读取图像并转换为灰度图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 全局阈值处理
_, thresh_global = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)# 自适应阈值处理
thresh_adaptive = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY, 11, 2)# Otsu's 阈值处理
_, thresh_otsu = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 显示结果
cv2.imshow('Global Thresholding', thresh_global)
cv2.imshow('Adaptive Thresholding', thresh_adaptive)
cv2.imshow('Otsu Thresholding', thresh_otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. 应用场景

  • 文档图像的二值化:用于将扫描的文档图像转换为黑白图像,以便进一步的 OCR(光学字符识别)处理。
  • 物体检测:在自动化检测系统中,阈值处理可以用于分割目标物体,以便进行形状分析或特征提取。
  • 医学图像处理:用于分割细胞、器官或其他生物结构。

阈值处理是图像预处理中常用的步骤,尤其适合对噪声较少、对比度较高的图像进行处理。根据具体应用的需要,可以选择合适的阈值处理方法。

总结

  • 全局阈值适合简单、光照均匀的图像,计算速度快但对复杂场景效果不好。
  • 自适应阈值适合光照不均的复杂图像,能更好地处理细节,但计算复杂度较高。
  • Otsu’s 阈值法是一种自动选择阈值的全局方法,适合灰度直方图呈双峰分布的图像。

这篇关于opencv之阈值处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1126235

相关文章

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

使用Python处理CSV和Excel文件的操作方法

《使用Python处理CSV和Excel文件的操作方法》在数据分析、自动化和日常开发中,CSV和Excel文件是非常常见的数据存储格式,ython提供了强大的工具来读取、编辑和保存这两种文件,满足从基... 目录1. CSV 文件概述和处理方法1.1 CSV 文件格式的基本介绍1.2 使用 python 内

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

opencv实现像素统计的示例代码

《opencv实现像素统计的示例代码》本文介绍了OpenCV中统计图像像素信息的常用方法和函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 统计像素值的基本信息2. 统计像素值的直方图3. 统计像素值的总和4. 统计非零像素的数量

MyBatis延迟加载的处理方案

《MyBatis延迟加载的处理方案》MyBatis支持延迟加载(LazyLoading),允许在需要数据时才从数据库加载,而不是在查询结果第一次返回时就立即加载所有数据,延迟加载的核心思想是,将关联对... 目录MyBATis如何处理延迟加载?延迟加载的原理1. 开启延迟加载2. 延迟加载的配置2.1 使用

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超