19.OpenCV图像二值化
OpenCV图像二值化
图像二值化(Binarization)是图像预处理中的一种常用技术,其目的是将图像中的像素值分为两个类别——通常是“前景”和“背景”或者说0和255。二值化能够简化图像信息,为后续的形态学处理、边缘检测、目标识别等任务提供基础。本文将介绍二值化的基本概念、全局二值化、三角二值化和自适应二值化的原理与实现
1. 二值化基本概念
二值化将一幅灰度图像中的像素值根据阈值 TT 分为两类:
- 当像素值大于 TT 时,将其设为最大值(如 255);
- 当像素值小于或等于 TT 时,将其设为最小值(如 0)。
数学上可以表示为:
g ( x , y ) = { maxValue , if f ( x , y ) > T 0 , if f ( x , y ) ≤ T g(x,y)=\begin{cases}\text{maxValue}, & \text{if } f(x,y) > T \\0, & \text{if } f(x,y) \leq T\end{cases} g(x,y)={maxValue,0,if f(x,y)>Tif f(x,y)≤T
其中f(x,y)为原始图像像素值,g(x,y) 为二值化后的像素值。
2. 全局阈值二值化
全局阈值二值化是最简单的二值化方法,它使用一个固定阈值对整幅图像进行处理。OpenCV 提供了 cv::threshold 函数来实现这一过程。
2.1 cv::threshold 函数
函数原型如下:
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type);
- 返回值:函数返回所使用的阈值,当使用
THRESH_OTSU或THRESH_TRIANGLE时,该值为计算出的最佳阈值,否则返回thresh。 - src:输入灰度图像。
- dst:输出二值图像。
- thresh:阈值 TT。
- maxval:当像素值大于阈值时赋予的值(通常为 255)。
- type:
THRESH_BINARY:像素值大于阈值时设为最大值,否则设为 0。THRESH_BINARY_INV:像素值大于阈值时设为 0,否则设为最大值。THRESH_TRUNC:像素值大于阈值时设为阈值,否则保持原值。THRESH_TOZERO:像素值大于阈值时保持原值,否则设为 0。THRESH_TOZERO_INV:像素值大于阈值时设为 0,否则保持原值。THRESH_OTSU:自动计算最佳阈值,并使用THRESH_BINARY进行二值化。THRESH_TRIANGLE:基于直方图形状分析自动选择阈值,适用于单峰或近似单峰直方图。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;int main() {// 读取灰度图像Mat gray = imread("E:/image/lena.png", IMREAD_GRAYSCALE);if (gray.empty()) {cerr << "图像加载失败!" << endl;return -1;}imshow("原图", gray);Mat binary;// 使用不同阈值类型进行二值化threshold(gray, binary, 128, 255, THRESH_BINARY);imshow("THRESH_BINARY", binary);threshold(gray, binary, 128, 255, THRESH_BINARY_INV);imshow("THRESH_BINARY_INV", binary);threshold(gray, binary, 128, 255, THRESH_TRUNC);imshow("THRESH_TRUNC", binary);threshold(gray, binary, 128, 255, THRESH_TOZERO);imshow("THRESH_TOZERO", binary);threshold(gray, binary, 128, 255, THRESH_TOZERO_INV);imshow("THRESH_TOZERO_INV", binary);waitKey(0);destroyAllWindows();return 0;
}
在上述示例中使用了128作为阈值,推荐平均值作为阈值效果会好。我们使用了不同的阈值类型进行二值化,并分别显示了处理后的结果如下图。

3. Otsu’s 自动阈值法
当图像的灰度直方图呈双峰分布时,Otsu 自动阈值法可以自动选择最佳阈值,从而实现自适应二值化。使用方法是在 cv::threshold 函数中加入 THRESH_OTSU 标志。
3.1 Otsu 示例代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;int main() {Mat gray = imread("E:/image/lena.png", IMREAD_GRAYSCALE);if (gray.empty()) {cerr << "图像加载失败!" << endl;return -1;}Mat binary;// thresh 参数可以设为 0,Otsu 算法会自动计算最佳阈值double otsu_thresh_val = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);cout << "Otsu 自动选择的阈值为:" << otsu_thresh_val << endl;imshow("原始灰度图像", gray);imshow("Otsu 二值化", binary);waitKey(0);return 0;
}

4. 三角二值化(Triangle Thresholding)
三角二值化(Triangle Thresholding)是一种基于图像直方图分析的方法,适用于单峰或近似单峰直方图的情况。它使用直方图的形状特征来确定一个合适的阈值。该方法通常用于光照均匀、前景与背景灰度分布明显的图像。不适用于双峰或多峰直方图(例如 Otsu 方法更适用于双峰直方图)
4.1 三角二值化原理
- 计算图像灰度直方图。
- 选择直方图中的最大峰值点作为基准点。
- 计算从直方图起始点到峰值点之间的最大距离来确定阈值。
4.2 三角二值化示例代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;int main() {// 读取灰度图像Mat gray = imread("lena.png", IMREAD_GRAYSCALE);if (gray.empty()) {cerr << "图像加载失败!" << endl;return -1;}Mat binary;// 使用 Triangle 方法自动计算阈值double triangle_thresh_val = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);cout << "三角阈值计算结果:" << triangle_thresh_val << endl;imshow("原始灰度图像", gray);imshow("Triangle 二值化", binary);waitKey(0);return 0;
}

5. 自适应阈值二值化
在光照不均匀的场景下,全局阈值方法可能效果不佳,此时自适应阈值二值化更为有效。OpenCV 提供了 cv::adaptiveThreshold 函数,根据局部邻域信息动态确定阈值。
5.1 cv::adaptiveThreshold 函数
函数原型如下:
void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue,int adaptiveMethod, int thresholdType, int blockSize, double C);
- src:输入灰度图像。
- dst:输出二值图像。
- maxValue:二值化后像素的最大值(通常为 255)。
- adaptiveMethod:自适应方法,如
ADAPTIVE_THRESH_MEAN_C(邻域均值)或ADAPTIVE_THRESH_GAUSSIAN_C(高斯加权)。 - thresholdType:阈值类型(通常为
THRESH_BINARY)。 - blockSize:用于计算局部阈值的邻域大小(必须为奇数)。
- C:从计算出的平均值中减去的常数,起到微调作用。
5.2 自适应阈值示例代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;int main() {Mat gray = imread("E:/image/lena.png", IMREAD_GRAYSCALE);if (gray.empty()) {cerr << "图像加载失败!" << endl;return -1;}Mat adaptive_binary;// 使用自适应阈值,将邻域均值作为局部阈值,blockSize 为 11,C 为 2adaptiveThreshold(gray, adaptive_binary, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, 2);imshow("原始灰度图像", gray);imshow("自适应阈值二值化", adaptive_binary);waitKey(0);return 0;
}
自适应阈值方法通过考虑局部信息,使得在光照不均时也能得到较好的二值化结果,可以看到更多的细节

6. 应用场景与小结
图像二值化是图像预处理的重要步骤,全局阈值、Otsu 自动阈值和自适应阈值各有适用场景。
- 全局阈值:简单、快速,适用于光照均匀的图像;
- Otsu 方法:自动计算最佳阈值,适用于双峰直方图;
- 自适应阈值:针对局部光照不均效果较好。
通过选择合适的方法和参数,可以有效分离图像中的前景与背景,为后续的图像处理和分析任务打下良好基础。
主要应用场景:
- 文档处理:二值化能将文档转换为黑白图像,有助于 OCR 识别。
- 目标分割:二值化用于将前景与背景分离,便于后续的物体检测和形态学处理。
- 图像分析:二值化简化了图像信息,适合形状分析和轮廓提取。
相关文章:
19.OpenCV图像二值化
OpenCV图像二值化 图像二值化(Binarization)是图像预处理中的一种常用技术,其目的是将图像中的像素值分为两个类别——通常是“前景”和“背景”或者说0和255。二值化能够简化图像信息,为后续的形态学处理、边缘检测、目标识别等…...
通过Appium理解MCP架构
MCP即Model Context Protocol(模型上下文协议),是由Anthropic公司于2024年11月26日推出的开放标准框架,旨在为大型语言模型与外部数据源、工具及系统建立标准化交互协议,以打破AI与数据之间的连接壁垒。 MCP架构与Appi…...
分享一个Pyside6实现web数据展示界面的效果图
今天又是有问题直接找DS的一天,每日一问,今天我的问题是“怎么将pyside6生成的界面转成web界面,使用python语言实现web界面”,等了一会,DS给我提供了两种方案,方案如下: 然后,让我们…...
FALL靶场通关攻略
1,下载好靶机后打开,通过kali扫描靶机ip和端口,得到靶机ip为192.168.50.144 2,扫描目录 3,访问靶机 4,访问扫描到的test.php,得到缺少GET请求参数的提示 5,使用FUZZ来扫出参数为file 6ÿ…...
Mybatis日志模块分析--适配器模式+代理模式
适配器模式 日志在我们开发过程中占据了一个非常重要的地位,是开发和运维管理之间的桥梁,在Java中的日志框架也非常多,Log4j,Log4j2,Apache Commons Log,java.util.logging,slf4j等,这些工具对外的接口也都不尽相同,为…...
HTTP介绍以及(GET/POST/PUT/DELETE)应用介绍
WWW 是 “World Wide Web” 的缩写,中文名为 “万维网”。它是一个基于超文本和 HTTP 协议的全球性信息系统,通过互联网连接了世界各地的服务器和用户。用户可以使用浏览器访问各种网站,浏览网页、获取信息、进行交互等。 WWW 的核心技术包…...
圆球法线图,图生法线图 图片生成法线图
目录 圆球法线图 根据图片生成法线图 深度图计算法线图 圆球法线图 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D# 定义球体的参数 radius 1.0 resolution 100# 生成球体表面的点 u np.linspace(0, 2 * np.pi, resoluti…...
notepad++ 正则表达式
注意:Notepad正则表达式字符串最长不能超过69个字符 \ 转义字符 如:要使用 “\” 本身, 则应该使用“\\” \t Tab制表符 注:扩展和正则表达式都支持 \r 回车符CR 注:扩展支持,正则表达式不支持 \n 换行符…...
Java基于SpringBoot的网络云端日记本系统,附源码+文档说明
博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…...
【自用记录】本地关联GitHub以及遇到的问题
最近终于又想起GitHub,想上传代码和项目到仓库里。 由于很早之前有在本地连接过GitHub(但没怎么用),现在需要重新搞起(操作忘得差不多)。 在看教程实操的过程中遇到了一些小问题,遂记录一下。 前…...
页码设置相关问题记录
Q:中间没有显示页码怎么办? A:“页眉和页脚”-“页码”-“页面底端”-“普通数字2” Q:想让页码在某几节连续怎么办? A: ① 先保证节与节之间插入了“分节符”(如何插入分节符和如何显示分节符…...
什么是数据集市
数据集市(Data Mart)是数据管理领域的核心概念,其定义为面向特定业务领域或用户群体的小型数据仓库子集,专注于部门级业务分析,具有快速响应、灵活部署等特点。以下从定义、特点、类型、结构、应用场景及与其他数据架构…...
Python 的未来:在多元变革中持续领跑
一、从工具到生态:Python 的核心优势筑牢发展根基 Python 自诞生以来,始终以 “简洁易用” 和 “跨界融合” 为标签,在技术快速迭代的时代展现出惊人的韧性。其核心竞争力不仅在于语法的直观性 —— 让开发者专注于逻辑实现而非语法细节&…...
【HC-05蓝牙模块】主要性能指标与通信基础知识
一、HC-05 基础学习视频 HC-05蓝牙串口通信模块调试与应用1 二、HC-05学习视频课件...
深度学习中的数据类型
1. NumPy 数组 (numpy.ndarray) 核心定位:科学计算的基础工具,处理数值多维数组。 特点: 高效数值运算:底层用 C 实现,适合数学计算(如矩阵乘法、傅里叶变换)。 内存连续存储:数据…...
如何缩短研发周期,降低研发成本?全星APQP软件为您提供解决方案
如何缩短研发周期,降低研发成本?全星APQP软件为您提供解决方案 一、 系统概述 全星研发管理APQP软件系统是一款专为产品研发和质量管控打造的智能化平台,旨在帮助企业高效推进APQP(先期产品质量策划)流程,…...
嵌入式系统安全架构白皮书
嵌入式系统安全架构白皮书 一、安全威胁模型 1.1 典型攻击面分析 #mermaid-svg-mxWZ8IOtOmMv6YLV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-mxWZ8IOtOmMv6YLV .error-icon{fill:#552222;}#mermaid-svg-mxWZ8I…...
MQTT之重复消息(5、TCP重连和MQTT重连)
目录 1. TCP 协议层的重传(原生机制) 2. 触发 TCP 重传的具体场景 3、TCP 重传的关键参数(了解) 第一、重传超时(RTO - Retransmission Timeout) 第二、重传次数 第三、累计时间 vs 本次 RTO 的区别 第四.常见问题解答 第…...
Github Webhook 以及主动式
Github配置 GitHub 默认支持两种 Content-Type: application/json application/x-www-form-urlencoded 特别要注意 Content-Type 我们选择: application/json Flask代码 import os import shutil import subprocess from flask import Flask, request, jsonifyapp = Fla…...
猜猜我用的是哪个大模型?我的世界游戏界面简单的模拟效果
我的罗里吧嗦的,根据小朋友的要求,边听边写边输入的提示词: 请生成一段完整的在网页中用html5和javascript代码模拟“我的世界”中游戏场景的互动画面,要求提供若干人物选项可以选择,请自行选择需要使用哪些库或框架来…...
基于龙芯3A5000处理器,全国产标准6U VPX板卡解决方案
1,产品功能 本产品为一款高可靠性的基于龙芯3A5000处理器以及 7A2000芯片组的标准6U VPX板卡,具有以太网、SATA、PCIE,以及显示等接口,产品功能框图如图1所示: 图1 系统框图 2,技术指标 序号 项目 指标…...
Unity编辑器功能及拓展(3) —[Attribute]特性
在 Unity 中,[Attribute]格式的特性是用于扩展编辑器功能、控制序列化行为和调整 Inspector 显示,进行编辑器拓展的核心工具。 一.基础编辑器拓展 1.基础序列化控制 1.[SerializeField] 强制显示私有变量到Inspector 2.[HideInInspector] 隐藏该字段在Inspect…...
每日一题之既约分数
题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。 例如 3/4,1/8,7/1, 都是既约分数。 请问,有多少个既约分…...
C++作用域辨识详解
在 C 中,作用域(Scope)定义了变量、函数、类等标识符的可见性和生命周期。理解作用域对于编写清晰、高效的代码至关重要。以下是 C 中作用域的详细分类和说明。 1. 全局作用域(Global Scope) 全局作用域是指在所有函…...
wait的概念和使用方法
在C语言中,wait 函数主要用于进程管理,它是一个系统调用,定义在 <sys/wait.h> 头文件中,用于让父进程等待其子进程结束,并获取子进程的终止状态。下面为你详细介绍其概念和使用方法。 概念 wait 函数的原型如下…...
HarmonyOS NEXT——鸿蒙神策埋点(二)
在上一章我分享了鸿蒙客户端集成神策埋点sdk的过程,现在我们需要服务端的小伙伴配置集成服务端sdk接收处理数据信息,以下是集成的过程。 Java服务端sdk集成 1、获取神策数据平台url地址 1、导入集成: dependencies {compile com.sensorsda…...
编程考古-Borland JBuilder:一场关于Java灵魂的战争与救赎
本文也是填之前一位网友让谈谈JBuilder的一个坑,感谢各位技术爱好者的支持。感谢关注小编,你的关注,是我更新的动力。 本篇章节如下: 序章:JBuilder的黄金时代 Borland的JBuilder:纯技术主义的胜利 生死…...
【day4】数据结构刷题 树
6-1 二叉树的遍历 函数接口定义: void InorderTraversal( BinTree BT ); void PreorderTraversal( BinTree BT ); void PostorderTraversal( BinTree BT ); void LevelorderTraversal( BinTree BT ); 其中BinTree结构定义如下: typedef struct TNode *Po…...
Elea AI:以人工智能之力推动病理实验室革新的技术突破与实践探索
Elea AI:以人工智能之力推动病理实验室革新的技术分析 一、病理实验室现状与 Elea AI 的革新契机 (一)传统病理实验室的痛点剖析 在医疗体系中,病理实验室扮演着至关重要的角色,其诊断结果是疾病确诊与后续治疗方案制定的关键依据。然而,当前传统病理实验室在实际运作过…...
相似度计算 ccf-csp 2024-2-2
#include<bits/stdc.h> using namespace std;int main() {// 定义两个变量 n 和 m,分别用于存储两篇文章的单词个数int n, m;// 从标准输入读取 n 和 m 的值cin >> n >> m;// 定义三个 map 容器,A 用于存储并集,T 用于标记…...
