06 OpenCV‘阈值处理、自适应处理与ostu方法
1 基本概念
CV2中使用阈值的作用是将灰度图像二值化,即将灰度图像的像素值根据一个设定的阈值分成黑白两部分。阈值处理可以用于图像分割、去除噪声、增强图像对比度等多个领域。例如,在物体检测和跟踪中,可以通过对图像进行阈值处理来提取目标区域;在图像增强中,可以使用阈值处理来增强图像的轮廓和细节等。
阈值处理可以使用cv2.threshold()
函数来完成。
retval, dst = cv2.threshold(src, thresh, maxval, type)
其中,参数解释如下:
src
:输入图像,可以是灰度图像或彩色图像。thresh
:设定的阈值。maxval
:二值化后的最大值。当type
为cv2.THRESH_BINARY
或cv2.THRESH_BINARY_INV
时,像素值大于阈值的部分会设置为maxval
,否则会设置为0。type
:二值化操作的类型,包括:cv2.THRESH_BINARY
:二值化操作,大于阈值的像素值设置为maxval
,小于等于阈值的像素值设置为0。cv2.THRESH_BINARY_INV
:反向二值化操作,大于阈值的像素值设置为0,小于等于阈值的像素值设置为maxval
。cv2.THRESH_TRUNC
:截断操作,大于阈值的像素值设置为阈值,小于等于阈值的像素值保持不变。cv2.THRESH_TOZERO
:像素值小于等于阈值的设置为0,大于阈值的保持不变。cv2.THRESH_TOZERO_INV
:像素值大于等于阈值的设置为0,小于阈值的保持不变。
cv2.threshold()
函数的返回值为一个元组,包括:
retval
:实际使用的阈值。dst
:二值化后的输出图像。
2 二值化处理
灰度图像
通过对灰度图像进行二值处理,可以在图形中只保留两种颜色,通常我们设定为255(白色)和0(黑色),但也可根据需求设置为黑色和灰色的二值图像,如:
import cv2
img = cv2.imread("lenacolor.png", 0) # 将图像读成灰度图像
t1, dst1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # 二值化阈值处理
t2, dst2 = cv2.threshold(img, 127, 200, cv2.THRESH_BINARY)
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
cv2.destroyAllWindows()
彩色图像
同样这一方法可用于彩色图像,通过对某一通道进行二值化,使图像的颜色变得更加夸张,如:
import cv2 img = cv2.imread('lenacolor.png')
b, g, r = cv2.split(img) # 将BGR通道分离 # 对红色通道进行阈值处理
t1, r = cv2.threshold(r, 127, 255, cv2.THRESH_BINARY) img_after = cv2.merge([b, g, r]) cv2.imshow('original', img)
cv2.imshow('threshold', img_after)
cv2.waitKey(0)
cv2.destroyAllWindows()
反二值化处理
反二值化处理(Inverse Thresholding)是二值化处理的一种变体,其作用是将灰度图像的像素值根据一个设定的阈值分成两部分,但是与普通二值化处理不同的是,反二值化处理将像素值大于阈值的部分设置为0,小于等于阈值的部分设置为最大像素值,即产生一个反色的二值化图像。代码中type需要设置为cv2.THRESH_BINARY_INV
。
防止视觉疲劳,后面的图换了一下示例图像
3 零处理
低于阈值零处理
低于阈值的部分会被处理为0,此时填入的maxval
无效
对灰度图来说,低于阈值的部分将会被处理为黑色;对于RGB彩图来说,低于阈值的部分图像会变暗。
import cv2
img1 = cv2.imread("test.png", 0) # 将图像读成灰度图像
img2 = cv2.imread("test.png") b, g, r = cv2.split(img2) # 将BGR通道分离 t1, dst1 = cv2.threshold(img1, 127, 255, cv2.THRESH_TOZERO) # 低于阈值零处理
cv2.imshow('img1', img1)
cv2.imshow('dst1', dst1) t2, b = cv2.threshold(b, 127, 255, cv2.THRESH_TOZERO) # 低于阈值零处理
img_after = cv2.merge([b, g, r])
cv2.imshow('img2', img2)
cv2.imshow('img_after', img_after) cv2.waitKey()
cv2.destroyAllWindows()
超出阈值零处理
类似反二值化处理。将超出某一阈值的部分进行归零处理。超出阈值零处理可以在一些特定的场合下使用,例如在一些需要保留一定程度的图像细节的场合,超出阈值零处理可以避免将过多的像素值直接设置为0或最大像素值,从而使图像保留更多的细节信息。
4 截断处理
该方法传入的type是cv2.THRESH_TRUNC
,代码结构与前面高度重合,此处不再贴代码。
截断处理是二值化处理的一种变体,其作用是将灰度图像的像素值根据一个设定的阈值分成两部分,但是与普通的二值化处理不同的是,超出阈值的部分不会被设置为0或最大像素值,而是被截断为阈值本身。
图像截断处理通常适合用于需要保留图像主要信息的场合,而又不需要进行明显的二值化操作的场合。在这种情况下,截断处理可以使得图像保留更多的灰度级,从而能够更好地保留图像中的细节和信息,同时又能够去除一些噪声或者不需要的部分。
5 自适应处理
自适应阈值处理是图像处理中的一种常见操作,可以根据图像局部的灰度特征来自适应地确定阈值,以达到更好的二值化效果。在OpenCV中,可以使用cv2.adaptiveThreshold()
函数进行自适应阈值处理。
相比于阈值处理,自适应处理具有以下优点:
- 自适应处理可以根据局部像素的灰度值特征来确定二值化阈值,从而适应图像的不同区域和不同光照条件,能够更好地突出图像中的目标物体。
- 自适应处理可以在处理过程中保留更多的细节信息,减少因阈值过大或过小而造成的信息丢失,提高图像处理的准确性。
- 自适应处理适用于复杂背景下的目标物体分割,特别是在背景区域灰度分布不均的情况下,能够更好地处理背景区域和目标区域的差异。
自适应处理相比于阈值处理具有更好的适应性和灵活性,可以在不同的图像处理场景中应用。当图像的灰度分布不均、光照条件不同或需要保留更多的细节信息时,自适应处理通常是更好的选择。
cv2.adaptiveThreshold()
函数的基本语法如下:
dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
其中:
src
:输入图像,必须为灰度图像。maxValue
:二值化后的最大值。adaptiveMethod
:自适应阈值处理的方法,包括:cv2.ADAPTIVE_THRESH_MEAN_C
:基于均值的自适应阈值处理。cv2.ADAPTIVE_THRESH_GAUSSIAN_C
:基于高斯加权平均值的自适应阈值处理。
thresholdType
:阈值类型,与普通二值化处理相同,包括:cv2.THRESH_BINARY
:二值化操作,大于阈值的像素值设置为maxValue
,小于等于阈值的像素值设置为0。cv2.THRESH_BINARY_INV
:反向二值化操作,大于阈值的像素值设置为0,小于等于阈值的像素值设置为maxValue
。
blockSize
:每个像素点周围用来计算阈值的像素数。必须是奇数。C
:阈值校正值。该值会被加到均值或加权平均值上,用于调整阈值。
cv2.adaptiveThreshold()
函数的返回值为二值化后的输出图像。
仍以上一张图像为例:
import cv2 image_Gray = cv2.imread("test.png", 0) # 自适应阈值的计算方法为cv2.ADAPTIVE_THRESH_MEAN_C
athdMEAM = cv2.adaptiveThreshold\ (image_Gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 0)
# 自适应阈值的计算方法为cv2.ADAPTIVE_THRESH_GAUSSIAN_C
athdGAUS = cv2.adaptiveThreshold\ (image_Gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY, 5, 0)
# 显示自适应阈值处理的结果
cv2.imshow("MEAN_C", athdMEAM)
cv2.imshow("GAUSSIAN_C", athdGAUS)
cv2.waitKey()
cv2.destroyAllWindows()
可以看出自适应阈值似乎保留了更多细节,但此处效果并不好,也就说明自适应并不能完全代替人工选择。(对于人脸图像,该方法的效果会比上图更好一些)
6 Ostu方法
Otsu’s method 是一种经典的自适应阈值处理算法,可以自动确定图像的二值化阈值。该算法可以将图像中的像素值分为两部分,从而将图像转换为二值图像。在 OpenCV 中,可以使用cv2.threshold()
函数进行 Otsu’s method 处理。在type中,输入对应的方法名+cv2.THRESH_OTSU
即可调用该方法。该方法的存在也是threshold将阈值作为返回值的意义所在。
在 Otsu’s method 中,不需要预先指定阈值,而是通过计算图像灰度直方图和类间方差来确定阈值。具体来说,该方法会计算每一个像素灰度值作为阈值时,将图像分为前景和背景两部分的类间方差,然后选取类间方差最大的像素灰度值作为二值化阈值。
import cv2img = cv2.imread('test.png', 0)
ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)cv2.imshow('original', img)
cv2.imshow('Otsu threshold', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
相关文章:

06 OpenCV‘阈值处理、自适应处理与ostu方法
1 基本概念 CV2中使用阈值的作用是将灰度图像二值化,即将灰度图像的像素值根据一个设定的阈值分成黑白两部分。阈值处理可以用于图像分割、去除噪声、增强图像对比度等多个领域。例如,在物体检测和跟踪中,可以通过对图像进行阈值处理来提取目…...

月薪过万的那些人,大部分都是做什么工作的?
三百六十行,行行出状元。不管是什么行业,月薪过万都是有的。只不过有些行业就是比较容易出现月薪过万,换句话说,就是这个行业内出现月薪过万的人数比较多。先说结论,综合来看月薪过万的这部分90后,大部分集…...

csgo搬砖项目,门槛最低的副业就是它(内附入门知识及选品技巧)
CSGO搬砖如何选择游戏饰品(装备)?相信很多朋友一定很关心这个问题,因为如何选品直接关系到该装备是否快速出售,而且也关系到账号整体盈收状况。那么今天阿阳就来好好聊聊如何选择Steam装备以及饰品的各项知识点。 Steam搬砖如何选…...

【闲聊杂谈】高并发下基于LVS的负载均衡
1、使用http协议进行网络请求 在前几年公布的用户入网数据中,移动入网的数量已经达到六七亿的规模,固网用户数也达到三至五个亿。想要解决这么大并发访问的场景,有多种的解决方案,常规有基于4层的,也有基于7层的。这个…...

Redis新数据类型
目录 Bitmaps 简介 命令 Bitmaps和set对比 HyperLogLog 介绍 命令 Geospatial 简介 命令 Bitmaps 简介 现代计算机用二进制(位)作为信息的基本单位,1个字节等于8位。合理的使用和操作位可以有效的提高内存的使用率和开发效率。 redis提供了Bitmaps这个"数据类…...

使用Python绘制股票CCI指标曲线
本文使用Python语言绘制一只股票的CCI(Commodity channel index)曲线,论文参考《Commodity channel index: Tool for trading cyclic trends》,该指标可以用来测量股价、外汇或者贵金属交易是否已超出常态分布范围, …...

【C语言技能树】浮点数在内存中的存储
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...

Spring框架源码(五) @configuration源码深度解析
Configuration 注解是spring-context模块提供的一个给开发者使用的配置类注解,开发者可以通过Configuration注解来定义配置类,也可以使用xml形式注入。 例如配置数据库配置,定义一个配置类,注入数据源DataSource, 事务管理器Trans…...
gcc/g++从入门到精通(3)gcc头文件、库搜索路径方式全面盘点
🎀 关于博主👇🏻👇🏻👇🏻 🥇 作者简介: 热衷于知识探索和分享的技术博主。 💂 csdn主页::【奇妙之二进制】 ✍️ 微信公众号:【Linux 世界】 🎉精彩专栏: 🎓 【面向工作git基础教程】 🧡 【C++11新特性深入剖析】 📚【shell脚本编程基础与...

Android Studio多渠道打包及自动化构建
Android 有不同的应用市场,也就是不同的渠道,需要为每个应用市场打一个安装包,但主要的代码是一样的,可能部分资源不一样,部分代码不一样,如果每个渠道都需要修改,然后打包,非常耗时…...

基于MATLAB的MIMO信道估计(附完整代码与分析)
目录 一. 介绍 二. MATLAB代码 三. 运行结果与分析 一. 介绍 本篇将在MATLAB的仿真环境中对比MIMO几种常见的信道估计方法的性能。 有关MIMO的介绍可看转至此篇博客: MIMO系统模型构建_唠嗑!的博客-CSDN博客 在所有无线通信中,信号通过…...
Python代码游戏————星球大战
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放,树高千尺,落叶归根人生不易,人间真情 目录 一.Python介绍 二.游戏效果呈现 三.主代码 四....
java向Word模板中替换书签数据,插入图片,插入复选框,插入Word中表格的行数据,删除表格行数据
java向Word模板中替换书签数据,插入图片,插入复选框,插入Word中表格的行数据,删除表格行数据 使用插件:spire.doc 创建工具类,上代码: import com.spire.doc.Document; import com.spire.doc.…...
Java基础知识快速盘点(二)
一,类型转换 隐式转换 将一个类型转换为另一个类型时,系统默认转换常量优化机制算术运算时类型的隐式转换(byte,short在算术运算时都会转换为int)char类型在进行运算时会根据其编码值进行运算 显式转换 二࿰…...

企业降本增效的催化剂:敏捷迭代
伴随着开源技术的大爆发,新一代的软件技术如雨后春笋般层出不穷。每家企业在硬件及软件开发上都有许多开源技术可选,目的还是在于提高效率,降低开发成本。 本篇文章,带大家了解下促进企业降本增效的重要理念:敏捷迭代…...

MySQL入门篇-MySQL高级窗口函数简介
备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊MySQL高级窗口函数 窗口函数在复杂查询以及数据仓库中应用得比较频繁 与sql打交道比较多的技术人员都需要掌握 如需要scott用户下建表及录入数据语句,可参考:scott建表及录入数据sql脚本 分析函数有3个基本组成…...
什么是 API(应用程序接口)?
API(应用程序接口)是一种软件中介,它允许两个不相关的应用程序相互通信。它就像一座桥梁,从一个程序接收请求或消息,然后将其传递给另一个程序,翻译消息并根据 API 的程序设计执行协议。API 几乎存在于我们…...

如何在外网访问内网的 Nginx 服务?
计算机业内人士对Nginx 并不陌生,它是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,除了nginx外,类似的apache、tomcat、IIS这几种都是主流的中间件。 Nginx 是在 BSD-like 协议下发行的&…...

vue2中defineProperty和vue3中proxy区别
区别一:defineProperty 是对属性劫持,proxy 是对代理对象 下面我们针对一个对象使用不同的方式进行监听,看写法上有什么不同。 // 原始对象 const data {name: Jane,age: 21 }defineProperty defineProperty 只能劫持对象的某一个属性&…...
将bean注入Spring容器的五种方式
前言 我们在项目开发中都用到Spring,知道对象是交由Spring去管理。那么将一个对象加入到Spring容器中,有几种方法呢,我们来总结一下。 ComponentScan Component ComponentScan可以放在启动类上,指定要扫描的包路径;…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...