内容来源于《opencv4应用开发入门、进阶与工程化实践》
二值分析:
常见的二值化方法:
- 基于全局阈值(threshold)得到的二值图像;
- 基于自适应阈值(adaptiveThreshold)得到的二值图像;
- 边缘检测(Canny)
- 基于像素值范围(inRange)
threshold
thresholdType介绍:
THRESH_BINARY
表示大于thresh
的取maxval
,否则取0;THRESH_BINARY_INV
表示大于thresh
的取0,否则取maxvalue
;THRESH_TRUNC
表示大于thresh
取threshold
,否则不改变灰度值;THRESH_TOZERO
表示大于thresh
的不改变灰度值,否则取0;THRESH_TOZERO_INV
表示大于thresh
取0,窦泽不改变灰度值;THRESH_OTSU
表示使用otsu
自动计算阈值;THRESH_TRIANGLE
表示使用Triangle
自动计算阈值;
adaptiveThreshold
void adaptiveThreshold( InputArray src, OutputArray dst,
double maxValue, int adaptiveMethod,
int thresholdType, int blockSize, double C );
src
表示需要进行二值化的图像;需要注意的是,该输入必须是8-bit单通道的图像;dst
表示输出图像的二值图像;maxValue
是一个非零值,用于对哪些满足条件的阈值进行赋值;adaptiveMethod
表示选择哪一种自适应阈值算法;Opencv提供两种,ADAPTIVE_THRESH_MEAN_C
与ADAPTIVE_THRESH_GAUSSIAN_C
,下面会详细介绍;thresholdType
表示二值化类型,OpenCV提供两种,THRESH_BINARY
与THRESH_BINARY_INV
,下面会详细介绍;blocksize
表示参与计算的像素的领域范围,必须使用奇数;C
可以为正数, 零或者负数;用于在计算过程中容忍程度;
thresholdType介绍
adaptiveMethod介绍
第一种ADAPTIVE_THRESH_MEAN_C
,针对像素(x,y)的计算方式如下:
- T(x,y)结果是在(x,y)的邻域blockSize×blockSize范围内所有灰度值的均值减去C�;
第二种ADAPTIVE_THRESH_GAUSSIAN_C
,针对像素(x,y)的计算方式如下:
- 首先,生成一个大小为blockSize×blockSize的高斯核,作为权重;
- 其次,利用高斯核与(x,y)邻域范围内灰度值,进行加权求和,再减去C,得到T(x,y);
高斯核:符合高斯分布,距离越近权重越大。
Canny
标准的边缘检测算法包括如下几步:
- 将图像转为灰度图像
- 通过高斯模糊卷积实现降噪
- 计算图像梯度的大小与角度
- 非最大信号压制
- 双阈值边缘连接
在图像利用Sobel
算子(也是滤波函数)计算x, y
两个方向的梯度:
其次,计算梯度的强度和方向:(根据X轴和Y轴方向的梯度可以计算图像中像素点的梯度幅值G与角度θ)
非最大抑制
理想情况下只有边缘像素的梯度是大于阈值T的,但实际情况下,局部也会出现多个高梯度阈值,所以要需要每个像素根据自身角度方向与两侧像素梯度值进行比较,如果当前像素点的梯度值小于两侧像素的梯度值,则将当前像素点的值设置为0;如果大于两侧像素的梯度值则保留。
双阈值连接
双阈值连接时保证边缘连续的关键步骤。一个高阈值H,一个低阈值L。
双阈值连接首先使用L对梯度图像进行处理,高于L保留,低于L丢弃,并将值设为零。然后使用H进行处理,高于H都视为边缘像素点。梯度值在[L,H]之间的:如果从低阈值像素点出发,最终可以通过相邻的像素点连接到高阈值像素点,而且整个连线上的像素点梯度值都大于L,则保留;否则设置为0。
轮廓发现与轮廓绘制
轮廓发现:
void findContours//提取轮廓,用于提取图像的轮廓
(
InputOutputArray image,//输入图像,必须是8位单通道图像,并且应该转化成二值的
OutputArrayOfArrays contours,//检测到的轮廓,每个轮廓被表示成一个point向量
OutputArray hierarchy,//可选的输出向量,包含图像的拓扑信息。其中元素的个数和检测到的轮廓的数量相等
int mode,//说明需要的轮廓类型和希望的返回值方式
int method,//轮廓近似方法
Point offset = Point()
)
轮廓绘制:
void drawContours//绘制轮廓,用于绘制找到的图像轮廓
(
InputOutputArray image,//要绘制轮廓的图像
InputArrayOfArrays contours,//所有输入的轮廓,每个轮廓被保存成一个poi