这是比普通 Threshold 强大 10 倍的核心函数,专门解决光照不均匀、局部明暗差异大的图像(比如阴影、反光、拍照偏光的文档)。
普通 Cv2.Threshold 是全局一个阈值,遇到阴影直接废;
而 AdaptiveThreshold 是每个像素自己算局部阈值,抗光照干扰极强!
一、它到底是什么?
自适应阈值 = 局部阈值化
- 对图像每一个小区域单独计算阈值
- 解决:阴影、反光、光照不均、局部亮度变化
- 典型用途:扫描文档文字提取、银行卡 / 证件识别、暗背景文字、低光图像二值化
一句话区别:
- Threshold:整张图用 同一个阈值(简单但怕光照)
- AdaptiveThreshold:每个像素用 周围区域算出的阈值(复杂但鲁棒)
二、函数原型(C# / OpenCVSharp)
void AdaptiveThreshold(
InputArray src, // 输入图像(必须 8位 单通道灰度图)
OutputArray dst, // 输出二值图像
double maxValue, // 满足条件后的最大值(一般 255)
AdaptiveThresholdTypes adaptiveType, // 自适应算法
ThresholdTypes thresholdType, // 阈值类型(只能是 二值/反向二值)
int blockSize, // 局部区域大小(必须 奇数:3,5,7...)
double C // 微调常数(阈值减去 C)
);
重要:无返回值
它不像普通 Threshold 返回阈值,因为每个像素的阈值都不一样。
三、所有参数逐行详解
1. src(输入)
- 必须是 8 位 单通道灰度图
- 彩色图必须先转灰度:
Cv2.CvtColor(..., ColorConversionCodes.BGR2GRAY)
2. dst(输出)
- 二值化图像(黑 0 / 白 maxValue)
3. maxValue(最大值)
- 常用:255(白色)
- 只有二值化时用到
4. adaptiveType(自适应算法)
2 种选择,决定 “局部阈值怎么算”:
① AdaptiveThresholdTypes.MeanC(均值法)
- 阈值 = 像素周围
blockSize×blockSize区域的平均值 - C - 速度快,适合大部分文档、文字
② AdaptiveThresholdTypes.GaussianC(高斯加权均值)
- 阈值 = 周围区域高斯加权平均值 - C
- 更平滑,对噪声、斑点更鲁棒
- 推荐优先使用!
5. thresholdType(阈值类型)
这里只能用 2 种! 不能用别的!
ThresholdTypes.Binary:正常二值化ThresholdTypes.BinaryInv:反向二值化
99% 场景用 BinaryInv(白底黑字 → 黑底白字更清晰)
6. blockSize(局部窗口大小)
- 必须是 奇数:3、5、7、9、11 ...
- 越小:细节越多,噪声也多
- 越大:越平滑,细节丢失
- 常用:9、11、15
7. C(微调常数)
- 最终阈值 = 局部均值 - C
- C 越大,文字越粗、越黑
- C 越小,文字越细、容易断
- 经验值:2 ~ 15 之间
四、计算公式(一看就懂)
以 GaussianC + BinaryInv 为例:
阈值 = 高斯加权局部均值 - C 如果 原像素 > 阈值 → 黑色(0) 否则 → 白色(255)
五、最实用、最标准的代码示例
using OpenCVSharp;
using OpenCVSharp.Flag;
class Program
{
static void Main()
{
// 1. 读图片
Mat src = Cv2.ImRead("document.jpg", ImreadModes.Color);
// 2. 转灰度(必须!)
Mat gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
// 3. 自适应阈值(最常用组合)
Mat dst = new Mat();
Cv2.AdaptiveThreshold(
gray, // 原图
dst, // 输出
255, // 最大值
AdaptiveThresholdTypes.GaussianC, // 高斯(推荐)
ThresholdTypes.BinaryInv, // 反向二值化(文字清晰)
blockSize: 15, // 窗口大小(奇数)
C: 9 // 微调常数
);
// 保存结果
Cv2.ImWrite("result.png", dst);
}
}
六、2 种自适应算法对比
表格
| 类型 | 原理 | 速度 | 噪声 | 推荐场景 |
|---|---|---|---|---|
| MeanC | 算术平均 | 快 | 一般 | 清晰文档、无噪点 |
| GaussianC | 高斯加权平均 | 稍慢 | 很低 | 绝大多数场景首选 |
七、参数怎么调?(超实用经验)
blockSize 怎么选?
- 文字小 → 用 9
- 文字大 → 用 11、15
- 图像噪声大 → 用 15、21
C 怎么调?
- 文字太淡、断断续续 → C 调大(如 9→12)
- 文字太粗、连在一起 → C 调小(如 9→6)
- 背景脏 → C 调大
八、自适应阈值 VS 普通阈值
表格
| 特性 | 普通 Threshold | 自适应 AdaptiveThreshold |
|---|---|---|
| 阈值 | 全局一个 | 每个像素局部计算 |
| 抗光照 | 差 | 极强 |
| 阴影 | 失效 | 完美处理 |
| 速度 | 极快 | 较慢 |
| 适用 | 光照均匀 | 文档、低光、阴影、反光 |
九、最常见的坑(90% 的人踩过)
- 输入不是灰度图 → 直接报错
- blockSize 不是奇数 → 报错
- 用了 Otsu → 自适应阈值不支持 Otsu
- thresholdType 用了 ToZero/Trunc → 报错(只支持 Binary/BinaryInv)
- C 值太大 / 太小 → 文字全黑 或 全消失
若文章对您有帮助,可以激励一下我哦,祝您平安幸福!
| 微信 | 支付宝 |
|---|---|
![]() |
![]() |

