OpenCV(cv::adaptiveThreshold())
cv::adaptiveThreshold()
是 OpenCV 中用于自适应阈值处理的函数。它主要用于将灰度图像二值化,特别是在图像照明不均匀或对比度差的情况下表现良好。
1. 函数
void adaptiveThreshold(
InputArray src, // 输入图像
OutputArray dst, // 输出二值图像
double maxValue, // 最大值
int adaptiveMethod, // 自适应阈值计算方法
int thresholdType, // 阈值类型
int blockSize, // 邻域块大小
double C // 常数C
);
参数:
src
: 输入的灰度图像(必须为单通道的 8 位图像)。dst
: 输出的二值化图像,与输入图像src
大小相同。maxValue
: 当条件满足时要赋予的最大值(即二值化后的高值,一般设为 255 表示白色)。adaptiveMethod
: 自适应阈值的计算方式,支持以下两种:cv::ADAPTIVE_THRESH_MEAN_C
: 邻域块内所有像素的平均值作为阈值。cv::ADAPTIVE_THRESH_GAUSSIAN_C
: 邻域块内所有像素的加权平均值(权值为高斯窗口)作为阈值。
thresholdType
: 阈值类型,有两种选择:cv::THRESH_BINARY
: 大于阈值的像素点被赋值为maxValue
,否则为 0。cv::THRESH_BINARY_INV
: 小于阈值的像素点被赋值为maxValue
,否则为 0。
blockSize
: 邻域块的大小,必须是奇数(如 3、5、7 等)。此参数定义计算自适应阈值的区域大小。C
: 一个常数值,它从计算出的自适应阈值中减去,用来调整阈值的灵活性。如果C
为正数,结果的阈值会降低;为负数时会增大。
工作原理:
cv::adaptiveThreshold()
函数根据输入图像的局部区域(即 blockSize
大小的块)来计算每个像素的阈值,因此可以很好地处理由于光照不均匀等原因导致的图像亮度差异。
具体来说,对于每个像素的二值化,不是简单地使用全局固定阈值,而是根据该像素邻域内的像素值来计算一个局部阈值。如果该像素值大于这个局部阈值,则该像素被设置为 maxValue
,否则设置为 0。
- 当使用
cv::ADAPTIVE_THRESH_MEAN_C
时,自适应阈值是邻域内像素的平均值减去常数C
。 - 当使用
cv::ADAPTIVE_THRESH_GAUSSIAN_C
时,自适应阈值是邻域内像素加权平均值(使用高斯加权)减去常数C
。
2. 示例
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
// 读取灰度图像
Mat src = imread("image.jpg", IMREAD_GRAYSCALE);
// 检查图像是否加载成功
if(src.empty()) {
return -1;
}
// 定义输出图像
Mat dst;
// 自适应阈值处理
adaptiveThreshold(src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, 2);
// 显示原图和二值化后的图像
imshow("Original Image", src);
imshow("Adaptive Threshold Image", dst);
waitKey(0);
return 0;
}
说明:
- 在上述示例中,输入图像
src
经过cv::adaptiveThreshold()
函数处理后输出到dst
。我们使用ADAPTIVE_THRESH_MEAN_C
方法和THRESH_BINARY
类型,将每个像素与其邻域的平均值相比,并进行二值化处理。 blockSize
设置为 11,表示计算每个像素阈值时考虑其周围 11x11 的邻域块。C
设置为 2,这意味着计算出的阈值会减去 2 来进行调整。
优点:
- 适应性强: 适用于光照变化大的场景,不受整体图像亮度的影响。
- 局部化处理: 通过邻域窗口的大小控制二值化效果,灵活性较高。
使用场景:
- 适合处理光照不均匀的文档图像、手写字符识别等场景。
- 在背景复杂或对比度不均的图像中,自适应阈值能有效提升图像分割效果。
通过调整 blockSize
和 C
参数,你可以根据不同图像场景调整阈值策略,以获得理想的分割效果。