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_OTSU 或 THRESH_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;
}
相关推荐
坐吃山猪1 天前
果蝇AI06-Mac部署实操
人工智能·深度学习·机器学习·果蝇ai
微尘hjx1 天前
【Deep-OC-SORT 02】多轨迹算法Deep-OC-SORT-相对 OC-SORT 的改进点
人工智能·算法·yolo·目标跟踪·视觉检测·ultralytics·deep-oc-sort
梦帮科技1 天前
意识启发式量子隧穿退火算法用于全局优化 (CITA) 完整技术指南
网络·人工智能·算法·量子计算·模拟退火算法
波儿菜1 天前
Xcode MCP 助力运行时二进制分析
人工智能·程序员·汇编语言
Vol火山1 天前
从买工具到建能力:数字化部门如何把 AI 变成可复制的生产力
人工智能
莱茶荼菜1 天前
【slam公式】
人工智能·线性代数·机器学习
Henry-SAP1 天前
SAP PP中的核心业务流程——离散制造、重复制造、流程制造三大模式解析
前端·数据库·人工智能·制造
Zhao-Jichao1 天前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记
敢敢のwings1 天前
TACDYN-WAM 深度解读:机器人如何预测接触变化,并据此生成动作
人工智能·机器学习·机器人
沉默王二1 天前
阿里版Codex,再次惊艳到我了。
人工智能·openai·agent