OpenCv之图像二值化

目录

一、图像二值化的核心本质

[二、OpenCV 中二值化的核心方法](#二、OpenCV 中二值化的核心方法)

[2.1 固定阈值二值化(cv::threshold)](#2.1 固定阈值二值化(cv::threshold))

[2.2 自动最优固定阈值(Otsu / 三角法)](#2.2 自动最优固定阈值(Otsu / 三角法))

[2.3 自适应阈值二值化(cv::adaptiveThreshold)](#2.3 自适应阈值二值化(cv::adaptiveThreshold))

[三、 二值化测试代码和效果](#三、 二值化测试代码和效果)

[3.1 lean图测试三个算法](#3.1 lean图测试三个算法)

[3.2 以扫描文档处理为例](#3.2 以扫描文档处理为例)


一、图像二值化的核心本质

图像二值化是将灰度图像 (0~255)转换为纯黑白图像(仅 0 和 255 两个值)的过程,核心是通过「阈值」区分前景(目标)和背景:

  • 像素值 > 阈值 → 设为 255(白)
  • 像素值 ≤ 阈值 → 设为 0(黑)(或反向)

二值化是图像分割、轮廓检测、字符识别、缺陷检测 的基础,能大幅简化图像数据,突出目标区域。

二、OpenCV 中二值化的核心方法

OpenCV 提供两类二值化方法:固定阈值二值化 (手动设阈值)和自适应阈值二值化(自动算阈值),还有拓展的 Otsu / 三角法(自动找最优固定阈值)。

2.1 固定阈值二值化(cv::threshold)

cpp 复制代码
double threshold(
    InputArray src,       // 输入:单通道灰度图(必须!)
    OutputArray dst,      // 输出:二值化图像
    double thresh,        // 手动设定的阈值(0~255)
    double maxval,        // 超过阈值的像素赋值(通常255)
    int type              // 二值化类型
);

二值类型:

2.2 自动最优固定阈值(Otsu / 三角法)

核心原理: 无需手动设阈值,算法自动计算最优阈值 (最大化前景 / 背景分离度),只需在 type 后加 THRESH_OTSUTHRESH_TRIANGLE

  • THRESH_OTSU:适用于双峰直方图(前景和背景像素值分布明显分开);
  • THRESH_TRIANGLE:适用于单峰直方图(如医学图像、暗背景亮目标)。

2.3 自适应阈值二值化(cv::adaptiveThreshold)

核心原理: 针对光照不均 的图像(如阴影、渐变背景),为每个像素计算局部阈值 (以该像素为中心的邻域均值 / 高斯加权均值),能避免固定阈值的 "局部过曝 / 过暗" 问题。函数原型:

复制代码
void adaptiveThreshold(
    InputArray src,       // 输入:单通道灰度图
    OutputArray dst,      // 输出:二值化图像
    double maxValue,      // 最大值(通常255)
    int adaptiveMethod,   // 局部阈值计算方式
    int thresholdType,    // THRESH_BINARY/THRESH_BINARY_INV
    int blockSize,        // 邻域大小(奇数,如3、5、7、11)
    double C              // 常数:阈值 = 邻域均值 - C(调对比度)
);

关键参数

  • adaptiveMethod
    • ADAPTIVE_THRESH_MEAN_C:邻域算术均值作为阈值(速度快);
    • ADAPTIVE_THRESH_GAUSSIAN_C:邻域高斯加权均值作为阈值(效果更平滑);
  • blockSize:邻域越大,二值化越 "模糊";越小,越保留细节(需试 3/5/7/11);
  • C:减去的常数(正数→降低阈值,更多像素变白;负数→提高阈值,更多像素变黑)。

三、 二值化测试代码和效果

3.1 lean图测试三个算法

固定阈值 自动最优固定阈值和自适应阈值方法的二值化。

cpp 复制代码
void testBinaryImage()
{
	Mat GrayMat = imread(R"(D:\Study\OpenCvStudy\lean.jpg)", ImreadModes::IMREAD_GRAYSCALE);
	Mat Thresh_BinaryMat,Threah_BinaryInvMat,TruncMat,TozeoMat,TozeoInvMat;
	//阈值有效
	threshold(GrayMat, Thresh_BinaryMat, 125, 255, THRESH_BINARY);
	threshold(GrayMat, Threah_BinaryInvMat, 125, 255, THRESH_BINARY_INV);
	threshold(GrayMat, TruncMat, 125, 255, THRESH_TRUNC);
	threshold(GrayMat, TozeoMat, 125, 255, THRESH_TOZERO);
	threshold(GrayMat, TozeoInvMat, 125, 255, THRESH_TOZERO_INV);

	Mat Thresh_OTSU_Mat, Thresh_TRIANGLE_Mat;
	//两个算法自己取最优阈值 只支持灰度图
	threshold(GrayMat, Thresh_OTSU_Mat, 125, 255, THRESH_OTSU);
	threshold(GrayMat, Thresh_TRIANGLE_Mat, 125, 255, THRESH_TRIANGLE);
	//自适应法 均值法和高斯法
	Mat Thresh_Mean_Mat, Thresh_Gauss_Mat;
	adaptiveThreshold(GrayMat, Thresh_Mean_Mat,255, AdaptiveThresholdTypes::ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,55,0);
	adaptiveThreshold(GrayMat, Thresh_Gauss_Mat, 255, AdaptiveThresholdTypes::ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 55, 0);

	imshow("GrayMat", GrayMat);
	imshow("Thresh_BinaryMat", Thresh_BinaryMat);
	imshow("Threah_BinaryInvMat", Threah_BinaryInvMat);
	imshow("TruncMat", TruncMat);
	imshow("TozeoMat", TozeoMat);
	imshow("TozeoInvMat", TozeoInvMat);
	imshow("Thresh_OTSU_Mat", Thresh_OTSU_Mat);
	imshow("Thresh_TRIANGLE_Mat", Thresh_TRIANGLE_Mat);
	waitKey();
}

3.2 以扫描文档处理为例

cpp 复制代码
int testBinaryImage2() {
	// 读取灰度图(必须单通道!)
	Mat img = imread(R"(D:\Study\OpenCvStudy\Test.jpg)", ImreadModes::IMREAD_GRAYSCALE);
	if (img.empty()) return -1;

	// 固定阈值二值化(白底黑字)
	Mat binary1;
	threshold(img, binary1, 127, 255, THRESH_BINARY); // 阈值127

	// 反向二值化(黑底白字)
	Mat binary2;
	threshold(img, binary2, 127, 255, THRESH_BINARY_INV);


	// Otsu 自动找阈值(thresh设0即可,函数返回最优值)
	Mat Otusbinary;
	double otsu_thresh = threshold(img, Otusbinary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	cout << "Otsu 自动计算的最优阈值:" << otsu_thresh << endl;

	// 自适应阈值
	Mat binary_adaptive;
	adaptiveThreshold(
		img, binary_adaptive, 255,
		ADAPTIVE_THRESH_GAUSSIAN_C, // 高斯加权均值
		THRESH_BINARY_INV,          // 白底黑字
		11,                         // 邻域大小11×11
		2                           // 常数C=2
	);


	// 显示
	imshow("原图", img);
	imshow("THRESH_BINARY(白底黑字)", binary1);
	imshow("THRESH_BINARY_INV(黑底白字)", binary2);
	imshow("THRESH_OTSU(白底黑字)", Otusbinary);
	imshow("adaptiveThreshold(白底黑字)", binary_adaptive);
	waitKey(0);
	return 0;
}
相关推荐
空堂与归5 分钟前
序列数据怎么喂给神经网络?用循环神经网络RNN拆开一个时间步
人工智能·rnn·神经网络·nlp
尺度商业8 分钟前
大变革下的电力新序章:供需重塑、错配破解与价值重估
人工智能
天远Date Lab12 分钟前
零信任架构实战:基于天远车信盟出险构建自动化汽车消费贷合规网关
人工智能·机器学习·计算机视觉·ocr
知见漫记15 分钟前
AI文档总结折叠手机推荐,联想moto razr Fold让信息处理更高效
人工智能·智能手机
虎虎(_ _)。゜zzZ18 分钟前
Qdrant向量数据库工程实战
数据库·人工智能·大模型·向量数据库·rag·qdrant
DM今天肝到几点?19 分钟前
GPT-6 Astra 发布:ARC-AGI-3 从 7.8% 跳到 99.9%,OpenAI 宣告「欢迎进入 AGI 时代」
人工智能·gpt·深度学习·agi
智途 Tech25 分钟前
2026年分析多个Excel、CSV和网页数据的AI工具清单:Tabbit 浏览器多源引用
大数据·人工智能·excel
李妍.26 分钟前
PyTorch GPU 版安装记录(RTX 5060 + Python 3.14)
人工智能·pytorch·python
海天一色y27 分钟前
注意力机制的进化:MHA → GQA → MLA → CSA → HCA
人工智能·注意力机制
广慈新医知31 分钟前
当健康问题越来越复杂,AI更适合先帮我们“把问题问清楚”
人工智能·python