上一节我们学习了几何图像变换函数的具体功能,相信大家学习之后,已经有所了解,本节了我们进入OpenCV学习的下一个模块Miscellaneous Image Transformations(各种各样的图像变换处理),首先我们学习本模块的第一个知识点,自适应阈值详解(adaptiveThreshold)。
1、函数原型
void adaptiveThreshold(InputArray src,
OutputArray dst,
double maxValue,
int adaptiveMethod,
int thresholdType,
int blockSize,
double C);
2、函数功能
对一幅灰度图像进行二值化,该函数支持就地操作;
该函数用下面的公式对一幅灰度图像进行二值化:
(1)正向二值化,THRESH_BINARY
正向二值化(2)反向二值化,THRESH_BINARY_INV
反向二值化3、参数详解
-
第一个参数,InputArray src,原图,即输入图像,是一个8位单通道的图像;
-
第二个参数,OutputArray dst,目标图像,与原图像具有同样的尺寸与类型;
-
第三个参数,double maxValue,分配给满足条件的像素的非零值;
-
第四个参数,int adaptiveMethod,自适应阈值的方法,通常有以下几种方法;
(1)ADAPTIVE_THRESH_MEAN_C,阈值T(x,y)是(x,y)减去C的Blocksize×Blocksize邻域的平均值。
(2)ADAPTIVE_THRESH_GAUSSIAN_C ,阈值T(x,y)是(x,y)减去C的Blocksize×Blocksize邻域的加权和(与高斯相关),默认sigma(标准差)用于指定的Blocksize;具体的情况可以参见getGaussianKernel函数;
- 第五个参数,int thresholdType,阈值的类型必须是以下两种类型,
(1)THRESH_BINARY,正向二值化
(2)THRESH_BINARY_INV ,反向二值化
-
第六个参数,int blockSize,像素邻域的大小,用来计算像素的阈值,blockSize必须为奇数,例如,3,5,7等等;
-
第七个参数,double C,从平均数或加权平均数减去常量。通常,它是正的,但也可能是零或负数。
4、阈值类型详解
阈值的类型(1)THRESH_BINARY,正向二值化,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值设置为maxval;否则,将该点的像素值设置为0;
具体的公式如下
(2)THRESH_BINARY_INV ,反向二值化,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值设置为0;否则,将该点的像素值设置为maxval;
具体的公式如下
(3)THRESH_TRUNC ,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值设置为threshold;否则,将该点的像素值不变;
具体的公式如下
(4)THRESH_TOZERO ,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值不变;否则,将该点的像素值设置为0;
具体的公式如下
(5)THRESH_TOZERO_INV ,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值设置为0;否则,将该点的像素值不变;
具体的公式如下
(6)THRESH_MASK
(7)THRESH_OTSU,使用Otsu算法选择最佳阈值。
(8)THRESH_TRIANGLE,使用三角算法选择最佳阈值。
5、具体实例
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
// 原图像
Mat srcImage,dstImage;
// 调整自适应阈值方法的变量
int g_AdaptiveMethod = 0;
// 调整阈值类型的变量
int g_ThresholdType = 0;
// 回调函数
static void OnAdaptiveMethod(int, void*);
int main(int argc, char** argv)
{
// 载入图像
srcImage = imread("lena.png");
// 判断图像是否为空
if (srcImage.empty())
{
printf("image error!");
return 0;
}
// 对原图像进行备份
dstImage = srcImage.clone();
namedWindow("原图");
imshow("原图", dstImage);
// 判断图像是彩色图像还是灰度图像
// 如果图像是彩色图像,需要将图像转换为灰度图像
if (srcImage.channels()==3)
{
cvtColor(srcImage, srcImage, COLOR_BGR2GRAY);
}
namedWindow("【效果图】");
// 创建trackbar
createTrackbar("自适应阈值方法:",
"【效果图】",
&g_AdaptiveMethod,
1,
OnAdaptiveMethod);
createTrackbar("阈值类型:",
"【效果图】",
&g_ThresholdType,
1,
OnAdaptiveMethod);
// 调用回调函数
OnAdaptiveMethod(0, 0);
waitKey(0);
return 0;
}
void OnAdaptiveMethod(int, void*)
{
// 对图像进行自适应阈值二值化
adaptiveThreshold(srcImage,
dstImage,
255,
g_AdaptiveMethod,
g_ThresholdType,
3,
3);
imshow("【效果图】", dstImage);
}
实验结果
原图 ADAPTIVE_THRESH_MEAN_C + THRESH_BINARY ADAPTIVE_THRESH_MEAN_C + THRESH_BINARY_INV好了,今天的OpenCV学到这里就结束了,本节对自适应二值化的函数讲的很细,希望大家可以仔细的理解哦!!
我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C需要编程,C++需要编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!
网友评论