二值化技术详解

二值化技术详解

一、技术背景

二值化是图像处理中最基础的操作之一,它将灰度图像转换为只有黑白两色的图像。二值化后的图像便于进行轮廓检测、形态学操作、形状分析等后续处理。

本文详细介绍 Binary、BinaryInv、Otsu 等多种二值化模式的原理与区别,以及在 SEM 项目中 MorphologicalOperate.Binarize() 的应用。


二、数学原理

2.1 基本二值化(Binary)

基本二值化使用固定阈值将图像分为黑白两类:

g(x,y)={maxval,if f(x,y)>thresh0,otherwise g(x,y) = \begin{cases} maxval, & \text{if } f(x,y) > thresh \\ 0, & \text{otherwise} \end{cases} g(x,y)={maxval,0,if f(x,y)>threshotherwise

其中,threshthreshthresh 为阈值,maxvalmaxvalmaxval 为最大值(通常为255)。

2.2 反向二值化(BinaryInv)

反向二值化与基本二值化相反:

g(x,y)={maxval,if f(x,y)≤thresh0,otherwise g(x,y) = \begin{cases} maxval, & \text{if } f(x,y) \leq thresh \\ 0, & \text{otherwise} \end{cases} g(x,y)={maxval,0,if f(x,y)≤threshotherwise

2.3 截断二值化(Truncate)

截断二值化不改变低于阈值的像素:

g(x,y)={thresh,if f(x,y)>threshf(x,y),otherwise g(x,y) = \begin{cases} thresh, & \text{if } f(x,y) > thresh \\ f(x,y), & \text{otherwise} \end{cases} g(x,y)={thresh,f(x,y),if f(x,y)>threshotherwise

2.4 阈值归零(ThresholdToZero)

高于阈值的像素保持不变,低于阈值的设为0:

g(x,y)={f(x,y),if f(x,y)>thresh0,otherwise g(x,y) = \begin{cases} f(x,y), & \text{if } f(x,y) > thresh \\ 0, & \text{otherwise} \end{cases} g(x,y)={f(x,y),0,if f(x,y)>threshotherwise

2.5 反向阈值归零(ThresholdToZeroInv)

低于阈值的像素保持不变,高于阈值的设为0:

g(x,y)={0,if f(x,y)>threshf(x,y),otherwise g(x,y) = \begin{cases} 0, & \text{if } f(x,y) > thresh \\ f(x,y), & \text{otherwise} \end{cases} g(x,y)={0,f(x,y),if f(x,y)>threshotherwise

2.6 Otsu 自适应阈值

Otsu方法通过最大化类间方差自动确定阈值:

σb2(k)=ω0ω1(μ0−μ1)2 \sigma_b^2(k) = \omega_0\omega_1(\mu_0 - \mu_1)^2 σb2(k)=ω0ω1(μ0−μ1)2

最佳阈值 k∗=arg⁡max⁡kσb2(k)k^* = \arg\max_{k} \sigma_b^2(k)k∗=argmaxkσb2(k)


三、代码实现

以下代码来自 e:\SEM\Methods\MorphologicalOperate.cs:

csharp 复制代码
public static Mat Binarize(Mat img)
{
    var gray = ToGray(img);
    Mat result = new Mat();
    Cv2.Threshold(gray, result, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.BinaryInv);
    return result;
}

private static Mat ToGrayAndBinary(Mat img)
{
    var gray = ToGray(img);
    Cv2.Threshold(gray, gray, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
    return gray;
}

public static Mat ToGray(Mat img)
{
    if (img.Channels() > 1)
    {
        Mat gray = new Mat();
        Cv2.CvtColor(img, gray, ColorConversionCodes.BGR2GRAY);
        return gray;
    }
    return img.Clone();
}

二值化类型组合

在OpenCV中,可以通过位或运算组合不同的阈值类型:

csharp 复制代码
// Otsu + BinaryInv:自动阈值 + 反向二值化
Cv2.Threshold(gray, result, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.BinaryInv);

// Otsu + Binary:自动阈值 + 正常二值化
Cv2.Threshold(gray, result, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);

OpenCV API

csharp 复制代码
double Cv2.Threshold(
    Mat src,              // 输入灰度图像
    Mat dst,              // 输出图像
    double thresh,        // 阈值(Otsu时被忽略)
    double maxval,        // 最大值
    ThresholdTypes type   // 阈值类型
);

返回值为使用的阈值(Otsu时返回计算得到的阈值)。


四、参数调优

4.1 阈值类型选择

类型 特点 适用场景
Binary 亮区域为白,暗区域为黑 目标为亮色区域
BinaryInv 暗区域为白,亮区域为黑 目标为暗色区域(SEM图像常见)
Truncate 压缩高亮区域 限制过曝区域
ThresholdToZero 保留亮区域 提取亮特征
ThresholdToZeroInv 保留暗区域 提取暗特征

4.2 Otsu 与固定阈值的选择

场景 建议方法
图像光照均匀,有明确双峰 Otsu
图像光照变化大 自适应阈值(Adaptive Threshold)
需要稳定控制阈值 固定阈值
多幅图像批量处理 Otsu(自动适应每张图)

4.3 maxval 参数

通常设置为255(8位图像的最大值),但可以根据需要调整:

  • 设置为127:产生灰度二值图
  • 设置为1:产生0-1二值图

五、常见问题

Q1:使用 Otsu 时阈值参数设为多少?

解决方案 :使用 Otsu 时,thresh 参数会被忽略,可以设为任意值(通常设为0)。实际阈值由算法自动计算。

Q2:二值化结果全黑或全白?

原因:阈值设置不当或图像对比度极低。

解决方案:

  • 使用 Otsu 自动确定阈值
  • 先进行 CLAHE 对比度增强
  • 检查图像直方图分布

Q3:目标区域在二值化后不连续?

原因:阈值选择不当,目标区域灰度分布不均匀。

解决方案:

  • 使用形态学闭运算连接断裂区域
  • 考虑使用自适应阈值方法
  • 先进行高斯模糊平滑图像

Q4:如何获取 Otsu 计算的具体阈值?

csharp 复制代码
double threshold = Cv2.Threshold(gray, result, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
Console.WriteLine($"Otsu阈值: {threshold}");

Q5:Binary 和 BinaryInv 如何选择?

选择原则:

  • 目标区域灰度值较高:使用 Binary
  • 目标区域灰度值较低:使用 BinaryInv

在 SEM 图像分析中,孔隙、裂纹等目标区域通常呈现为暗色(低灰度值),因此常用 BinaryInv。

Q6:Otsu 与自适应阈值的区别?

特性 Otsu 自适应阈值
阈值数量 全局1个 局部多个
适用场景 光照均匀 光照不均匀
计算速度 快 较慢
细节保留 一般 好
相关推荐
程序人生8885 小时前
PDF 转 Word 版式错乱、表格丢失?DocConverter Web 格式互转引擎的保真实践
前端·人工智能·opencv·机器学习·pdf·word
AI日报派送佬8 小时前
Ultralytics YOLO 模型训练技巧与最佳实践
人工智能·python·深度学习·yolo·机器学习·计算机视觉
HUANGZHENXUAN1238 小时前
代码解析(一):从 `opencv_basics/` 说起
opencv
一木 之林10 小时前
Dify学习笔记 00 · 总览:56集四模块学习地图(从低代码平台到检索底座)
人工智能·计算机视觉·langchain
田威AI1 天前
图片内文字翻译的规格:输入输出、保真、自动化、时间与费用
前端·计算机视觉
hahaha60161 天前
FPGA+ARM实现AWB的全流程
人工智能·嵌入式硬件·算法·计算机视觉·fpga开发
PascalXie1 天前
免标定视觉伺服综述:严格定义、四级分类与端到端的边界
计算机视觉
岁月蹉跎的一杯酒1 天前
CCM-可调颜色校正与噪声权衡
图像处理·算法·isp
词却1 天前
OpenCV学习:MediaPipe 人脸网格检测
opencv·学习
ggb喔1 天前
52pojie 的图片工具:为什么无损转换后体积涨了 6 倍、照片方向还是歪的
图像处理·python·算法·计算机视觉·图形渲染·媒体