opencv基础篇 ——(三)图像二值化
图像二值化是图像处理中常用的一种技术,用于将灰度图像转换为只包含两个像素值(通常是黑色和白色)的二值图像。这种处理通常用于简化图像、减少数据量以及强调感兴趣的目标。
二值化方法
- 全局阈值二值化:
全局阈值二值化是最简单的二值化方法之一,它使用固定的阈值将图像的灰度值分为两个区域:高于阈值的像素被设为白色(255),低于阈值的像素被设为黑色(0)。
OpenCV 提供了 cv::threshold 函数来实现全局阈值二值化。
- 自适应阈值二值化:
自适应阈值二值化方法会根据图像局部区域的灰度值动态地计算阈值,因此适用于光照不均匀或者局部对比度较低的图像。
OpenCV 提供了 cv::adaptiveThreshold 函数来实现自适应阈值二值化。
- 基于直方图的二值化:
基于直方图的二值化方法会分析图像的灰度直方图,并根据直方图的特征来确定合适的阈值,例如 Otsu’s 二值化方法就是一种基于直方图的二值化方法。
OpenCV 中可以使用 cv::threshold 函数的 THRESH_OTSU 标志来实现 Otsu’s 二值化。
threshold二值化
cv::threshold 是 OpenCV 库中用于图像二值化处理的一个重要函数。它通过对输入图像中的像素值应用一个固定阈值或自适应阈值,将图像分割为二值(黑白)或多级灰度图像。二值化处理常用于图像预处理,有助于简化图像内容,提取边缘、轮廓等显著特征,或去除噪声。以下是 cv::threshold 函数的详细功能介绍:
函数说明
函数声明与参数:
double cv::threshold(
InputArray src,
OutputArray dst,
double thresh,
double maxval,
int type
);
-
**InputArray src: **输入图像,通常为 cv::Mat 类型,表示待二值化的多通道(1通道 或 3 通道)图像。确保输入图像已经正确加载且数据有效。
-
**OutputArray dst: **输出图像,同样为 cv::Mat 类型,用于存储二值化处理后的结果。该矩阵会被自动调整大小和类型以适应二值化结果。
-
double thresh: 阈值,用于决定像素值被归类为“背景”还是“前景”的临界值。像素值大于(或等于,取决于阈值类型)该阈值的像素将被设定为 maxval,其余像素设定为零或其他指定值。
-
double maxval: 二值化后“前景”像素的值。对于二值化处理,通常设为 255(最大灰度值),表示白色;对于多级阈值分割,可以设置为其他灰度值。
-
int type: 阈值类型,决定了阈值分割的具体规则。常见的阈值类型包括:
- cv::THRESH_BINARY: 传统的二值化阈值分割,像素值大于或等于 thresh 的像素被设定为 maxval(通常为白色),其余像素设为 0(黑色)。
- cv::THRESH_BINARY_INV: 与 cv::THRESH_BINARY 相反,像素值大于或等于 thresh 的像素设为 0,其余像素设为 maxval。
- cv::THRESH_TRUNC: 像素值大于 thresh 的部分被截断为 thresh,其余像素值保持不变。
- cv::THRESH_TOZERO: 像素值小于 thresh 的部分设为 0,大于或等于 thresh 的像素值保持不变。
- cv::THRESH_TOZERO_INV: 像素值大于或等于 thresh 的部分设为 0,小于 thresh 的像素值保持不变。
- cv::THRESH_OTSU: 自适应二值化,使用 Otsu’s 方法自动计算最佳阈值,并进行二值化处理(需结合 cv::THRESH_BINARY 或 cv::THRESH_BINARY_INV 使用)。
- 组合类型:可以将上述类型通过按位或 (|) 组合,如 cv::THRESH_BINARY | cv::THRESH_OTSU,实现自适应二值化。
cv::ThresholdTypes
### 功能与用途
- 二值化图像:cv::threshold 的核心功能是将输入图像转换为二值图像,即将每个像素值简化为两个离散的值,通常为黑色(0)和白色(255)。这一过程有助于突出图像中的边缘、轮廓或其他显著结构,为后续的图像分析和识别提供简化后的输入。
- 多级阈值分割:通过选择合适的 type 参数,可以实现多级阈值分割,将像素值划分为多个灰度等级。这种分割方式适用于需要区分更多灰度层次的场景,如医学影像分析、文本识别等。
- 自适应阈值计算:结合 cv::THRESH_OTSU 类型,cv::threshold 能够自动计算全局最优阈值,无需手动指定阈值。Otsu’s 方法根据图像直方图分布寻找最佳阈值,以最大化前景与背景像素的类间方差。
- 噪声抑制:通过设置合适的阈值,cv::threshold 可以有效地去除图像中的低灰度噪声,特别是在二值化过程中将低于阈值的像素设为背景(0),从而达到降噪效果。
示例
cv::Mat inputImage = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat binaryImage;
// 传统二值化,手动指定阈值
double thresholdValue = 128;
cv::threshold(inputImage, binaryImage, thresholdValue, 255, cv::THRESH_BINARY);
// 自适应二值化,自动计算阈值
cv::threshold(inputImage, binaryImage, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
注意事项:
- 阈值选择:对于手动指定阈值的情况,应根据图像内容和噪声水平选择合适的阈值。可以通过观察直方图或试错法来确定阈值。
- 异常处理:对于某些极端情况(如全黑或全白图像),cv::threshold 的结果可能不符合预期。在关键应用中,应对输出结果进行适当验证,并做好异常处理。
- 性能考量:二值化操作通常较快,但对大型图像进行自适应阈值计算(如使用 Otsu’s 方法)可能会增加计算时间。在实时或性能敏感的应用中,应考虑权衡计算成本与分割质量。
总结来说,cv::threshold 函数为 OpenCV 用户提供了强大的图像二值化和多级阈值分割功能,是图像处理和计算机视觉中不可或缺的预处理工具。通过合理选择阈值和阈值类型,可以有效简化图像内容、突出特征、抑制噪声,为后续的图像分析和识别任务奠定基础。在使用时,应注意输入图像格式、阈值选择以及性能考量等因素。
adaptiveThreshold自适应二值化
cv::adaptiveThreshold 是 OpenCV 库中用于图像二值化的一种方法,与常规的固定阈值方法(如 cv::threshold 函数)不同,它采用自适应阈值策略,即为图像中的每个像素点或邻域计算一个局部阈值来进行二值化。这种方法特别适用于图像中有较大局部光照变化或背景不均匀的情况,能够更好地保留图像细节并减少噪声影响。以下是 cv::adaptiveThreshold 函数的详细功能介绍:
函数说明
函数声明与参数:
void cv::adaptiveThreshold(
InputArray src,
OutputArray dst,
double maxValue,
int adaptiveMethod,
int thresholdType,
int blockSize,
double C
);
该函数根据以下公式将灰度图像转换为二进制图像
T(x,y) 值的计算可以参考AdaptiveThresholdTypes
-
InputArray src: 输入图像,通常为 cv::Mat 类型,表示待二值化的单通道(通常是灰度)图像。确保输入图像已经正确加载且数据有效。
-
OutputArray dst: 输出图像,同样为 cv::Mat 类型,用于存储自适应二值化处理后的结果。该矩阵会被自动调整大小和类型以适应二值化结果。
-
double maxValue: 二值化后“前景”像素的值。通常设为 255(最大灰度值),表示白色。
-
int adaptiveMethod: 自适应阈值计算方法,可选值包括:
- cv::ADAPTIVE_THRESH_MEAN_C: 使用邻域内像素的均值加上常数 C 作为阈值。
- cv::ADAPTIVE_THRESH_GAUSSIAN_C: 使用邻域内像素的加权均值(高斯权重)加上常数 C 作为阈值。这种方法对噪声有更好的抑制效果。
-
int thresholdType: 阈值类型,决定了像素值与阈值比较后的处理方式。与 cv::threshold 类似,支持以下类型:
- cv::THRESH_BINARY: 像素值大于等于局部阈值的像素设为 maxValue,其余像素设为 0。
- cv::THRESH_BINARY_INV: 像素值大于等于局部阈值的像素设为 0,其余像素设为 maxValue。
-
int blockSize: 定义计算局部阈值的邻域大小,以像素为单位。较大的块尺寸可以平滑图像变化,较小的块尺寸则能保留更多细节。一般选取奇数以确保中心像素。
-
double C: 常数,与 adaptiveMethod 中选择的方法结合,用于调整局部阈值。正值将增加阈值,负值将减小阈值。
AdaptiveThresholdTypes
cv::ADAPTIVE_THRESH_MEAN_C
使用邻域内像素的平均值加上一个常数 C 作为该像素位置处的阈值。公式如下:
cv::ADAPTIVE_THRESH_GAUSSIAN_C
使用邻域内像素值与高斯核的卷积结果(即加权均值)加上一个常数 C 作为阈值。高斯核赋予中心像素较高的权重,随着距离增大,周围像素的权重逐渐减小。这种方式对噪声有更好的抑制效果
功能与用途
-
自适应二值化:cv::adaptiveThreshold 的核心功能是基于图像中每个像素点周围的局部统计特性(如均值或加权均值)计算一个自适应阈值,并以此对像素进行二值化处理。这种自适应方法能有效应对光照不均匀、背景渐变等问题,相比固定阈值方法更能保留图像细节和准确分割物体。
-
局部阈值计算:通过设置 blockSize 参数,可以指定计算局部阈值时考虑的邻域大小。邻域内的像素值将按照所选的 adaptiveMethod(均值或加权均值)进行聚合,并加上常数 C 得到最终阈值。
-
噪声抑制:cv::ADAPTIVE_THRESH_GAUSSIAN_C 方法利用高斯加权均值,赋予中心像素更高的权重,对噪声有更好的抑制效果,尤其适合处理噪声较多的图像。
示例
cv::Mat inputImage = cv::imread("input_gray.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat binaryImage;
// 使用自适应阈值二值化,邻域大小为 31x31,使用高斯加权均值,常数 C = 6
cv::adaptiveThreshold(inputImage, binaryImage, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 31, 6);
注意事项:
-
输入图像格式:确保输入图像为单通道(通常是灰度)图像。如果是彩色图像,需先通过 cv::cvtColor 转换为灰度图像。
-
参数选择:blockSize 和 C 参数的选择对二值化结果有很大影响。应根据图像内容、噪声水平和所需细节保留程度进行试验调整。
-
性能考量:自适应阈值计算相对固定阈值方法更为耗时,尤其是在大图像和大邻域尺寸下。在实时或性能敏感的应用中,应评估计算成本与二值化效果的平衡。
-
边界处理:由于计算局部阈值时会考虑像素的邻域,图像边缘的像素可能无法获得完整的邻域信息。OpenCV 通常会对边缘像素进行某种形式的边界填充处理,但可能对边缘附近的二值化结果产生一定影响。
综上所述,cv::adaptiveThreshold 函数提供了一种基于局部统计特性的图像二值化方法,适用于处理光照不均匀、背景渐变或含有噪声的图像。通过合理选择参数,可以有效地进行图像分割、噪声抑制并保留图像细节,为后续的图像分析和识别任务提供高质量的二值化结果。在使用时,应注意输入图像格式、参数选择以及性能考量等因素。
效果展示
多通道二值化效果
- 单通道二值化(右上)与多通道二值化(右下),二值化会将像素值设为0与255, 因此多通二值化理论上会获得8种颜色
上图中,将小于200的像素点设置为0,但如果作用于findContours轮廓查找的话,最好是将背景设置为0,图像设置为1,有利于去查找。
- 展示阶段与反转类型的二值化
自适应二值化
自适应二值化,只支持单通道灰度图