opencv基础篇 ——(三)图像二值化

opencv基础篇 ——(三)图像二值化

图像二值化是图像处理中常用的一种技术,用于将灰度图像转换为只包含两个像素值(通常是黑色和白色)的二值图像。这种处理通常用于简化图像、减少数据量以及强调感兴趣的目标。

二值化方法

  • 全局阈值二值化:

全局阈值二值化是最简单的二值化方法之一,它使用固定的阈值将图像的灰度值分为两个区域:高于阈值的像素被设为白色(255),低于阈值的像素被设为黑色(0)。
OpenCV 提供了 cv::threshold 函数来实现全局阈值二值化。

  • 自适应阈值二值化:

自适应阈值二值化方法会根据图像局部区域的灰度值动态地计算阈值,因此适用于光照不均匀或者局部对比度较低的图像。
OpenCV 提供了 cv::adaptiveThreshold 函数来实现自适应阈值二值化。

  • 基于直方图的二值化:

基于直方图的二值化方法会分析图像的灰度直方图,并根据直方图的特征来确定合适的阈值,例如 Otsu’s 二值化方法就是一种基于直方图的二值化方法。
OpenCV 中可以使用 cv::threshold 函数的 THRESH_OTSU 标志来实现 Otsu’s 二值化。

threshold二值化

cv::threshold 是 OpenCV 库中用于图像二值化处理的一个重要函数。它通过对输入图像中的像素值应用一个固定阈值或自适应阈值,将图像分割为二值(黑白)或多级灰度图像。二值化处理常用于图像预处理,有助于简化图像内容,提取边缘、轮廓等显著特征,或去除噪声。以下是 cv::threshold 函数的详细功能介绍:

函数说明

函数声明与参数:

double cv::threshold(
    InputArray src,
    OutputArray dst,
    double thresh,
    double maxval,
    int type
);
  • **InputArray src: **输入图像,通常为 cv::Mat 类型,表示待二值化的多通道(1通道 或 3 通道)图像。确保输入图像已经正确加载且数据有效。

  • **OutputArray dst: **输出图像,同样为 cv::Mat 类型,用于存储二值化处理后的结果。该矩阵会被自动调整大小和类型以适应二值化结果。

  • double thresh: 阈值,用于决定像素值被归类为“背景”还是“前景”的临界值。像素值大于(或等于,取决于阈值类型)该阈值的像素将被设定为 maxval,其余像素设定为零或其他指定值。

  • double maxval: 二值化后“前景”像素的值。对于二值化处理,通常设为 255(最大灰度值),表示白色;对于多级阈值分割,可以设置为其他灰度值。

  • int type: 阈值类型,决定了阈值分割的具体规则。常见的阈值类型包括:

    • cv::THRESH_BINARY: 传统的二值化阈值分割,像素值大于或等于 thresh 的像素被设定为 maxval(通常为白色),其余像素设为 0(黑色)。
    • cv::THRESH_BINARY_INV: 与 cv::THRESH_BINARY 相反,像素值大于或等于 thresh 的像素设为 0,其余像素设为 maxval。
    • cv::THRESH_TRUNC: 像素值大于 thresh 的部分被截断为 thresh,其余像素值保持不变。
    • cv::THRESH_TOZERO: 像素值小于 thresh 的部分设为 0,大于或等于 thresh 的像素值保持不变。
    • cv::THRESH_TOZERO_INV: 像素值大于或等于 thresh 的部分设为 0,小于 thresh 的像素值保持不变。
    • cv::THRESH_OTSU: 自适应二值化,使用 Otsu’s 方法自动计算最佳阈值,并进行二值化处理(需结合 cv::THRESH_BINARY 或 cv::THRESH_BINARY_INV 使用)。
    • 组合类型:可以将上述类型通过按位或 (|) 组合,如 cv::THRESH_BINARY | cv::THRESH_OTSU,实现自适应二值化。

cv::ThresholdTypes

在这里插入图片描述

在这里插入图片描述### 功能与用途

  • 二值化图像:cv::threshold 的核心功能是将输入图像转换为二值图像,即将每个像素值简化为两个离散的值,通常为黑色(0)和白色(255)。这一过程有助于突出图像中的边缘、轮廓或其他显著结构,为后续的图像分析和识别提供简化后的输入。
  • 多级阈值分割:通过选择合适的 type 参数,可以实现多级阈值分割,将像素值划分为多个灰度等级。这种分割方式适用于需要区分更多灰度层次的场景,如医学影像分析、文本识别等。
  • 自适应阈值计算:结合 cv::THRESH_OTSU 类型,cv::threshold 能够自动计算全局最优阈值,无需手动指定阈值。Otsu’s 方法根据图像直方图分布寻找最佳阈值,以最大化前景与背景像素的类间方差。
  • 噪声抑制:通过设置合适的阈值,cv::threshold 可以有效地去除图像中的低灰度噪声,特别是在二值化过程中将低于阈值的像素设为背景(0),从而达到降噪效果。

示例

cv::Mat inputImage = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat binaryImage;

// 传统二值化,手动指定阈值
double thresholdValue = 128;
cv::threshold(inputImage, binaryImage, thresholdValue, 255, cv::THRESH_BINARY);

// 自适应二值化,自动计算阈值
cv::threshold(inputImage, binaryImage, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);

注意事项:

  • 阈值选择:对于手动指定阈值的情况,应根据图像内容和噪声水平选择合适的阈值。可以通过观察直方图或试错法来确定阈值。
  • 异常处理:对于某些极端情况(如全黑或全白图像),cv::threshold 的结果可能不符合预期。在关键应用中,应对输出结果进行适当验证,并做好异常处理。
  • 性能考量:二值化操作通常较快,但对大型图像进行自适应阈值计算(如使用 Otsu’s 方法)可能会增加计算时间。在实时或性能敏感的应用中,应考虑权衡计算成本与分割质量。

总结来说,cv::threshold 函数为 OpenCV 用户提供了强大的图像二值化和多级阈值分割功能,是图像处理和计算机视觉中不可或缺的预处理工具。通过合理选择阈值和阈值类型,可以有效简化图像内容、突出特征、抑制噪声,为后续的图像分析和识别任务奠定基础。在使用时,应注意输入图像格式、阈值选择以及性能考量等因素。

adaptiveThreshold自适应二值化

cv::adaptiveThreshold 是 OpenCV 库中用于图像二值化的一种方法,与常规的固定阈值方法(如 cv::threshold 函数)不同,它采用自适应阈值策略,即为图像中的每个像素点或邻域计算一个局部阈值来进行二值化。这种方法特别适用于图像中有较大局部光照变化或背景不均匀的情况,能够更好地保留图像细节并减少噪声影响。以下是 cv::adaptiveThreshold 函数的详细功能介绍:

函数说明

函数声明与参数:

void cv::adaptiveThreshold(
    InputArray src,
    OutputArray dst,
    double maxValue,
    int adaptiveMethod,
    int thresholdType,
    int blockSize,
    double C
);

该函数根据以下公式将灰度图像转换为二进制图像
在这里插入图片描述

T(x,y) 值的计算可以参考AdaptiveThresholdTypes

  • InputArray src: 输入图像,通常为 cv::Mat 类型,表示待二值化的单通道(通常是灰度)图像。确保输入图像已经正确加载且数据有效。

  • OutputArray dst: 输出图像,同样为 cv::Mat 类型,用于存储自适应二值化处理后的结果。该矩阵会被自动调整大小和类型以适应二值化结果。

  • double maxValue: 二值化后“前景”像素的值。通常设为 255(最大灰度值),表示白色。

  • int adaptiveMethod: 自适应阈值计算方法,可选值包括:

    • cv::ADAPTIVE_THRESH_MEAN_C: 使用邻域内像素的均值加上常数 C 作为阈值。
    • cv::ADAPTIVE_THRESH_GAUSSIAN_C: 使用邻域内像素的加权均值(高斯权重)加上常数 C 作为阈值。这种方法对噪声有更好的抑制效果。
  • int thresholdType: 阈值类型,决定了像素值与阈值比较后的处理方式。与 cv::threshold 类似,支持以下类型:

    • cv::THRESH_BINARY: 像素值大于等于局部阈值的像素设为 maxValue,其余像素设为 0。
    • cv::THRESH_BINARY_INV: 像素值大于等于局部阈值的像素设为 0,其余像素设为 maxValue。
  • int blockSize: 定义计算局部阈值的邻域大小,以像素为单位。较大的块尺寸可以平滑图像变化,较小的块尺寸则能保留更多细节。一般选取奇数以确保中心像素。

  • double C: 常数,与 adaptiveMethod 中选择的方法结合,用于调整局部阈值。正值将增加阈值,负值将减小阈值。

AdaptiveThresholdTypes

在这里插入图片描述

cv::ADAPTIVE_THRESH_MEAN_C
使用邻域内像素的平均值加上一个常数 C 作为该像素位置处的阈值。公式如下:

cv::ADAPTIVE_THRESH_GAUSSIAN_C
使用邻域内像素值与高斯核的卷积结果(即加权均值)加上一个常数 C 作为阈值。高斯核赋予中心像素较高的权重,随着距离增大,周围像素的权重逐渐减小。这种方式对噪声有更好的抑制效果

功能与用途

  • 自适应二值化:cv::adaptiveThreshold 的核心功能是基于图像中每个像素点周围的局部统计特性(如均值或加权均值)计算一个自适应阈值,并以此对像素进行二值化处理。这种自适应方法能有效应对光照不均匀、背景渐变等问题,相比固定阈值方法更能保留图像细节和准确分割物体。

  • 局部阈值计算:通过设置 blockSize 参数,可以指定计算局部阈值时考虑的邻域大小。邻域内的像素值将按照所选的 adaptiveMethod(均值或加权均值)进行聚合,并加上常数 C 得到最终阈值。

  • 噪声抑制:cv::ADAPTIVE_THRESH_GAUSSIAN_C 方法利用高斯加权均值,赋予中心像素更高的权重,对噪声有更好的抑制效果,尤其适合处理噪声较多的图像。

示例

cv::Mat inputImage = cv::imread("input_gray.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat binaryImage;

// 使用自适应阈值二值化,邻域大小为 31x31,使用高斯加权均值,常数 C = 6
cv::adaptiveThreshold(inputImage, binaryImage, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 31, 6);

注意事项:

  • 输入图像格式:确保输入图像为单通道(通常是灰度)图像。如果是彩色图像,需先通过 cv::cvtColor 转换为灰度图像。

  • 参数选择:blockSize 和 C 参数的选择对二值化结果有很大影响。应根据图像内容、噪声水平和所需细节保留程度进行试验调整。

  • 性能考量:自适应阈值计算相对固定阈值方法更为耗时,尤其是在大图像和大邻域尺寸下。在实时或性能敏感的应用中,应评估计算成本与二值化效果的平衡。

  • 边界处理:由于计算局部阈值时会考虑像素的邻域,图像边缘的像素可能无法获得完整的邻域信息。OpenCV 通常会对边缘像素进行某种形式的边界填充处理,但可能对边缘附近的二值化结果产生一定影响。

综上所述,cv::adaptiveThreshold 函数提供了一种基于局部统计特性的图像二值化方法,适用于处理光照不均匀、背景渐变或含有噪声的图像。通过合理选择参数,可以有效地进行图像分割、噪声抑制并保留图像细节,为后续的图像分析和识别任务提供高质量的二值化结果。在使用时,应注意输入图像格式、参数选择以及性能考量等因素。

效果展示

多通道二值化效果

  • 单通道二值化(右上)与多通道二值化(右下),二值化会将像素值设为0与255, 因此多通二值化理论上会获得8种颜色
    在这里插入图片描述

上图中,将小于200的像素点设置为0,但如果作用于findContours轮廓查找的话,最好是将背景设置为0,图像设置为1,有利于去查找。

  • 展示阶段与反转类型的二值化
    在这里插入图片描述

自适应二值化

在这里插入图片描述

自适应二值化,只支持单通道灰度图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/563853.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3中web前端JS动画案例(二)多物体运动-多值运动

<script setup> import { ref, onMounted, watch } from vue // ----------------------- 01 js 动画介绍--------------------- // 1、匀速运动 // 2、缓动运动&#xff08;常见&#xff09; // 3、透明度运动 // 4、多物体运动 // 5、多值动画// 6、自己的动画框架 // …

OWASP发布十大开源软件安全风险及应对指南

​ 最近爆发的XZ后门事件&#xff0c;尽管未酿成Log4j那样的灾难性后果&#xff0c;但它再次敲响了警钟&#xff1a;软件供应链严重依赖开源软件&#xff0c;导致现代数字生态系统极其脆弱。面对层出不穷的安全漏洞&#xff0c;我们需要关注开源软件 (OSS)风险 &#xff0c;改进…

干货 | 用几个语法打破你对Python的滤镜

Python现在是越来越火爆&#xff0c;不仅是风靡世界&#xff0c;还直接进入了中小学生的课堂。所以有越来越多的人想要尝试编程了。 想到以前当我第一次用代码打出“Hello, world”的时候&#xff0c;那种兴奋激动之情&#xff0c;真的是难以言表。 不过很多同学在刚入门的时…

nodejs在控制台打印艺术字

const figlet require("figlet");figlet("SUCCESS", function (err, data) {if (err) {console.log("Something went wrong...");console.dir(err);return;}console.log(data);}); 参考链接&#xff1a; https://www.npmjs.com/package/figlet…

Facebook账号运营要用什么IP?

众所周知&#xff0c;Facebook封号大多数情况都是因为IP的原因。Facebook对于用户账号有严格的IP要求和限制&#xff0c;以维护平台的稳定性和安全性。在这种背景下&#xff0c;海外IP代理成为了一种有效的解决方案&#xff0c;帮助用户避免检测&#xff0c;更加快捷安全地进行…

【LeetCode: 39. 组合总和 + 递归】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

程序员缓解工作压力的小窍门

目录 程序员缓解工作压力的小窍门 方向一&#xff1a;工作与休息的平衡 方向二&#xff1a;心理健康与自我关怀 方向三&#xff1a;社交与网络建设 程序员缓解工作压力的小窍门 程序员的工作性质常常伴随着高度的精神集中和持续的创新压力。为了保持高效和创新&#xff0c…

算法题解记录20+++

题目描述&#xff1a; 难度&#xff1a;简单 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来…

伪逆矩阵的两种求法

当矩阵的行列不相等&#xff0c;矩阵不是方阵时&#xff0c;求解矩阵的逆&#xff0c;可以使用伪逆的方法。 求解伪逆有两种方式。本文以mxn&#xff08;m<n&#xff09;的矩阵求解为例。 方法1&#xff1a;右伪逆 对于一个矩阵 和矩阵&#xff0c;如何矩阵之间满足&#…

3D模型人物换装系统(五 模型核批之后模型uv不正确)模型UV不正确

3D模型人物换装系统&#xff08;五 模型核批之后模型uv不正确&#xff09;模型UV不正确 介绍展示Maya导入查看uvUnity中测试分析没合批为什么没有问题总结 介绍 最近在公司里给公司做模型优化合批的时候发现了模型的uv在合批之后无法正常展示&#xff0c;这里找了很多的原因&a…

hadoop安装记录

零、版本说明 centos [rootnode1 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)jdk [rootnode1 ~]# java -version java version "1.8.0_311" Java(TM) SE Runtime Environment (build 1.8.0_311-b11) Java HotSpot(TM) 64-Bit Server VM (…

讲座回顾|DolphinDB 携手上海高金共探量化前沿

4月16日&#xff0c;由上海高级金融学院 MBA 量化投资俱乐部和上海交通大学量化分析协会联合举办的量化公开课如期在上海举行。DolphinDB 创始人兼 CEO 周小华博士作为演讲嘉宾受邀出席&#xff0c;针对如何利用中高频数据挖掘因子的话题&#xff0c;为大家分享了行业的前沿应用…

Nginx 代理配置

最近&#xff0c;工作中遇到需要用到 Nginx 实现正向web代理和反向web代理的需求&#xff0c;其中反向web代理需要支持发送HTTP 和 HTTPS请求 1. 正向代理 1.1. 正向代理 流程 下面以访问百度为例解释正向代理过程&#xff1a; 客户将浏览器代理地址设置为代理服务器地址和服…

入门产品经理你一定要知道的事(上)

产品&#xff08;Product&#xff09;是任何可以让人注意、获取、使用、或能够满足某种消费需求的东西。可以是实体产品、服务、人、组织、地点、思想等。 狭义上产品特指互联网产品&#xff0c;是关于软件、硬件的集合体。本期文章所说的产品是指互联网产品。 产品经理&#…

Spring Boot中JUnit 4与JUnit 5的如何共存

文章目录 前言一、先上答案二、稍微深入了解2.1 maven-surefire-plugin是什么2.2 JUnit4和JUnit5有什么区别2.2.1 不同的注解2.2.2 架构 前言 在maven项目中&#xff0c;生成单测时是否有这样的疑问&#xff1a;该选JUnit4还是JUnit5&#xff1f;在执行 mvn test 命令时有没有…

跳表:高效索引的神奇算法

跳表&#xff08;Skip List&#xff09;的设计思想基于二叉查找树和链表&#xff0c;它采用了一种多层次的思路&#xff0c;通过随机化的方式在每个节点添加多个后继节点&#xff0c;从而实现快速查找 跳表是一种数据结构&#xff0c;它以一种分层的方式来存储数据&#xff0c;…

百面算法工程师 | 分类和聚类

目录 6.1 为什么正确率有时不能有效评估分类算法&#xff1f; 6.2 什么样的分类器最好&#xff1f; 6.3 什么是聚类&#xff0c;你知道哪些聚类算法&#xff1f; 6.4 K-Means聚类算法如何调优? 6.5 K-Means聚类算法如何选择初始点? 6.6 K-Means聚类聚的是特征还是样本 …

一文掌握:数据湖是什么?可不是数据仓库

一、什么是数据湖 数据湖&#xff08;Data Lake&#xff09;是指一个大型数据存储和处理系统&#xff0c;它能够存储各种类型和格式的数据&#xff0c;包括结构化数据、半结构化数据和非结构化数据。数据湖的目的是为了让企业可以更好地管理和利用大量的数据&#xff0c;以便进…

Email API的安全性如何保障?API发信技巧?

Email API有哪些主要功能&#xff1f;如何选择邮箱API进行集成&#xff1f; Email API在企业和个人用户之间发挥着举足轻重的作用。然而&#xff0c;随着Email API的广泛应用&#xff0c;其安全性问题也逐渐凸显出来。那么&#xff0c;Email API的安全性究竟如何保障呢&#x…

基于 Grassmannian Manifold的动态图嵌入学习的脑网络时空枢纽识别

Spatiotemporal Hub Identification in Brain Network by Learning Dynamic Graph Embedding on Grassmannian Manifold 摘要 神经成像技术的进步使得测量不同大脑区域之间的连接随时间演变成为可能。新出现的证据表明&#xff0c;一些关键的大脑区域&#xff0c;称为枢纽节点…