【图像处理】OpenCV系列二十 --- 二值化函数详解(thr
上一节我们学习了用自适应阈值对一幅图像进行二值化,相信大家学习之后,已经有所了解,本节我们针对二值化这个概念我们进入深入的剖析,本节我们将学习二值化函数(threshold)的具体原理与用法!
1、函数原型
double threshold(InputArray src,
OutputArray dst,
double thresh,
double maxval,
int type);
2、函数功能
对数组元素进行固定阈值操作;并且该函数可以对多通道的数组用固定的阈值进行二值化;通常用于将灰度图像转换为二值化的图像;用于消除噪声,即滤除值过小或过大的像素;函数支持几种类型的阈值处理,由函数中的type参数决定;
另外,THRESH_OTSU or THRESH_TRIANGLE可以与type进行组合对图像进行二值化处理;在这些情况下,函数使用Otsu或者Triangle算法确定最优阈值,并使用它代替指定的阈值;
Note:
目前,Otsu或者Triangle算法仅支持8位单通道图像的实现,该函数支持就地操作哦!
返回值:
如果Otsu或者Triangle算法,则计算阈值。
3、参数详解
-
第一个参数,InputArray src,输入图像,可以是多通道图像、8位图像、32位浮点型图像;
-
第二个参数,OutputArray dst,目标图像,和原图像有一样的尺寸、类型和同样的通道数;
-
第三个参数,double thresh,进行二值化的阈值;
-
第四个参数,double maxval,最大值,一般与THRESH_BINARY或者THRESH_BINARY_INV阈值类型一起使用;
-
第五个参数,int type,阈值的类型;
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_ThresholdType = 0;
int g_ThresholdValue = 128;
// 回调函数
static void OnThresholdMethod(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("【效果图】");
createTrackbar("阈值大小:",
"【效果图】",
&g_ThresholdValue,
255,
OnThresholdMethod);
createTrackbar("阈值类型:",
"【效果图】",
&g_ThresholdType,
8,
OnThresholdMethod);
// 调用回调函数
OnThresholdMethod(0, 0);
waitKey(0);
return 0;
}
void OnThresholdMethod(int, void*)
{
Mat tmpImage = srcImage.clone();
// 设置二值化的类型
//目前,Otsu或者Triangle算法仅支持8位单通道图像的实现
// 因此与这两个算法组合的时候,需要将图像转换为灰度图像
if (g_ThresholdType==5)
{
if (srcImage.channels()==3)
cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
g_ThresholdType = THRESH_OTSU + THRESH_BINARY;
}
if (g_ThresholdType == 6)
{
if (srcImage.channels() == 3)
cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
g_ThresholdType = THRESH_OTSU + THRESH_BINARY_INV;
}
if (g_ThresholdType == 7)
{
if (srcImage.channels() == 3)
cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
g_ThresholdType = THRESH_TRIANGLE + THRESH_BINARY;
}
if (g_ThresholdType == 8)
{
if (srcImage.channels() == 3)
cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
g_ThresholdType = THRESH_TRIANGLE + THRESH_BINARY_INV;
}
// 二值化处理
threshold(tmpImage,
dstImage,
g_ThresholdValue,
255,
g_ThresholdType);
imshow("【效果图】", dstImage);
}
6、实验结果
原图 彩色图像正向二值化后效果图 彩色图像反向二值化后效果图 灰度图像正向二值化后效果图好了,今天的OpenCV学到这里就结束了,本节二值化函数(threshold)讲的清晰,希望大家可以仔细的理解哦!!
我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C语言编程,C++语言编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!