引言:
阈值化操作在图像处理中是一种常用的算法,比如图像的二值化就是一种最常见的一种阈值化操作。opencv2和opencv3中提供了直接阈值化操作cv::threshold()和自适应阈值化操作cv::adaptiveThreshold()两种阈值化操作接口,这里将对这两个接口进行介绍和对比。
1、直接阈值化——cv::threshold()
阈值化操作的基本思想是,给定一个输入数组和一个阈值,数组中的每个元素将根据其与阈值之间的大小发生相应的改变。opencv3中支持这一操作的接口是cv::threshold(),具体调用方法如下:
(1)第一个参数,InputArray 类型的 src,源图像。单通道,8 或 32位浮点数类型的深度。
(2)第二个参数,OutputArray 类型的 dst,输出图像。
(3)第三个参数,double 类型的 thresh,选取的阈值。
(4)第四个参数,double 类型的 maxval。
(5)第五个参数,int 类型的 type。阈值类型。如下所示:
代码示例:
#include "pch.h"
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
void CallBack_Size(int pos, void* userdata);
int thresholdVal = 0;
int thresholdMax = 255;
int thresholdType = 0;//0-4分别代表 二值化阈值操作、反二值化、截断、置0阈值操作、反置0阈值操作
int thresholdTypeMax = 4;
int main()
{
namedWindow("graysrc", WINDOW_AUTOSIZE);
namedWindow("graydst", WINDOW_AUTOSIZE);
Mat src = imread("F:\\visual studio\\Image\\lion.jpg");
if (src.empty())
{
cout << "Can't load the image" << endl;
return -1;
}
Mat graysrc;
cvtColor(src, graysrc, cv::COLOR_BGR2GRAY);
imshow("graysrc", graysrc);
createTrackbar("Threshold", "graydst", &thresholdVal, thresholdMax, CallBack_Size,(void *)&graysrc);
createTrackbar("ThresholdType", "graydst", &thresholdType, thresholdTypeMax, CallBack_Size, (void *)&graysrc);
waitKey(0);
}
void CallBack_Size(int pos,void* userdata)
{
Mat src = *((Mat*)userdata);
Mat dst;
//这里不可以使用pos,因为pos也可能代表thresholdType
threshold(src, dst, thresholdVal, thresholdMax, thresholdType);
imshow("graydst", dst);
}
效果如下:仅展示二值化和反二值化阈值操作的效果。
2.自适应阈值化——cv::adaptiveThreshold()
(1)第一个参数,InputArray 类型的 src,源图像。8 为单通道图像。
(2)第二个参数,OutputArray 类型的 dst,输出图像。
(3)第三个参数,double 类型的 maxValue,给像素赋的满足条件的非零值。
(4)第四个参数,int 类型的 adaptiveMethod,用于指定要使用的自适应阈值计算法,可取值为 ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C。
(5)第五个参数,int 类型的 thresholdType,阈值类型。取值必须为 THRESH_BINARY、THRESH_BINARY_INV 之一。
(6)第六个参数,int 类型的 blockSize,用于计算阈值大小的一个像素的邻域尺寸,取值为3、5、7等。
(7)第七个参数,double 类型的 C,减去平均或加权平均值后的常数值。通常为正数。
cv::adaptiveThreshold()支持两种自适应方法,即cv::ADAPTIVE_THRESH_MEAN_C(平均) 和cv::ADAPTIVE_THRESH_GAUSSIAN_C(高斯)。在两种情况下,自适应阈值T(x, y)。通过计算每个像素周围bxb大小像素块的加权均值并减去常量C得到。其中,b由blockSize给出,大小必须为奇数;如果使用平均的方法,则所有像素周围的权值相同;如果使用高斯的方法,则(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。
代码实例:
#include "pch.h"
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
void CallBack_Size(int pos, void* userdata);
int MaxValue = 255;
int method = 0; //0-ADAPTIVE_THRESH_MEAN_C 1-ADAPTIVE_THRESH_GAUSSIAN_C
int thresholdType = 0;//0-1分别代表 二值化阈值操作、反二值化
int thresholdTypeMax = 1;
int blocksize = 1;
int blocksizeMax = 10;
int main()
{
namedWindow("graysrc", WINDOW_AUTOSIZE);
namedWindow("graydst", WINDOW_AUTOSIZE);
Mat src = imread("F:\\visual studio\\Image\\women1.jpg");
if (src.empty())
{
cout << "Can't load the image" << endl;
return -1;
}
Mat graysrc;
cvtColor(src, graysrc, cv::COLOR_BGR2GRAY);
imshow("graysrc", graysrc);
createTrackbar("method", "graydst", &method, 1, CallBack_Size, (void *)&graysrc);
createTrackbar("ThresholdType", "graydst", &thresholdType, thresholdTypeMax, CallBack_Size, (void *)&graysrc);
createTrackbar("blocksize", "graydst", &blocksize, blocksizeMax, CallBack_Size, (void *)&graysrc);
//因为blocksize最小值为3
setTrackbarMin("blocksize", "graydst", 1);
CallBack_Size(0, (void *)&graysrc);
waitKey(0);
}
void CallBack_Size(int pos, void* userdata)
{
int size = 2 * blocksize + 1;
Mat src = *((Mat*)userdata);
Mat dst;
//这里不使用pos,因为其代表了不同的值。
adaptiveThreshold(src, dst, MaxValue, method, thresholdType, size, 0);
imshow("graydst", dst);
}
效果如下:
采用ADAPTIVE_THRESH_MEAN_C方法,,阈值类型为 THRESH_BINARY、THRESH_BINARY_INV时:
采用ADAPTIVE_THRESH_GAUSSIAN_C方法,,阈值类型为 THRESH_BINARY、THRESH_BINARY_INV时: