目录
[二、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;
}


