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;
}
相关推荐
lijianhua_97129 小时前
国内某顶级大学内部用的ai自动生成论文的提示词
人工智能
EDPJ9 小时前
当图像与文本 “各说各话” —— CLIP 中的模态鸿沟与对象偏向
深度学习·计算机视觉
蔡俊锋9 小时前
用AI实现乐高式大型可插拔系统的技术方案
人工智能·ai工程·ai原子能力·ai乐高工程
自然语9 小时前
人工智能之数字生命 认知架构白皮书 第7章
人工智能·架构
大熊背9 小时前
利用ISP离线模式进行分块LSC校正的方法
人工智能·算法·机器学习
eastyuxiao10 小时前
如何在不同的机器上运行多个OpenClaw实例?
人工智能·git·架构·github·php
诸葛务农10 小时前
AGI 主要技术路径及核心技术:归一融合及未来之路5
大数据·人工智能
光影少年10 小时前
AI Agent智能体开发
人工智能·aigc·ai编程
charlee4410 小时前
最小二乘问题详解17:SFM仿真数据生成
c++·计算机视觉·sfm·数字摄影测量·无人机航测
ai生成式引擎优化技术10 小时前
TSPR-WEB-LLM-HIC (TWLH四元结构)AI生成式引擎(GEO)技术白皮书
人工智能