1.threshold函数
double cv::threshold(InputArray src, OutputArray dst,
double thresh, double maxval, int type )
- src:待二值化的图像,图像只能是 CV_8U 和 CV_32F 两种数据类型。对于图像通道数目的要求与选择的二值化方法相关。
- dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型和通道数。
- thresh:二值化的阈值。
- maxval:二值化过程的最大值,它只在 THRESH_BINARY 和 THRESH_BINARY_INV 两种二值化方法中才使用。
- type:选择图像二值化方法的标志。
二值化方法可选择的标志及含义
标志参数
|
作用
|
---|---|
THRESH_BINARY
|
灰度值大于阈值的为最大值,其他值为
0
|
THRESH_BINARY_INV
|
灰度值大于阈值的为
0
,其他值为最大值
|
THRESH_TRUNC
|
灰度值大于阈值的为阈值,其他值不变
|
THRESH_TOZERO
|
灰度值大于阈值的不变,其他值为
0
|
THRESH_TOZERO_INV
|
灰度值大于阈值的为
0
,其他值不变
|
THRESH_OTSU
|
大津法自动寻求全局阈值
|
THRESH_TRIANGLE
|
三角形法自动寻求全局阈值
|
为了方便讲解,我们使用如下的一个图像,红色表示图像,黑色是图像的边界,蓝色是阈值
原图
1.1 THRESH_BINARY
- 大于阈值,取最大值。
- 小于等于阈值取0。
公式:
对于原图,如果我们进行二值化操作,那么蓝色的线以上的,都变成最大值,蓝色的线以下的线都变成0
1.2 THRESH_BINARY_INV
- 大于阈值,取0。
- 小于等于阈值,取最大值。
公式:
对于原图,如果我们进行反二值化操作,那么蓝色的线以下的,都变成最大值,蓝色的线以上的线都变成0
1.3 THRESH_TRUNC
- 大于阈值,取阈值
- 小于等于阈值,取原值
公式:
对于原图,如果我们进行截断操作
1.4 THRESH_TOZERO
- 大于阈值的,取原值。
- 小于等于阈值,取0
公式:
对于原图,如果我们进行操作
1.5 THRESH_TOZERO_INV
- 大于阈值的,取0。
- 小于等于阈值,取原值
公式:
对于原图,如果我们进行操作
1.6 代码示例
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("../pic/gril_1.jpg");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
imshow("原画", img);
Mat gray;
double a , b ,c ,d ;
cvtColor(img, gray, COLOR_BGR2GRAY);
Mat img_B, img_B_V, gray_B,gray_B_V, gray_T, gray_T_V, gray_TRUNC ;
//彩色图像二值化
threshold(img, img_B, 125, 255, THRESH_BINARY);
threshold(img, img_B_V, 125, 255, THRESH_BINARY_INV);
imshow("img_B", img_B);
imshow("img_B_V", img_B_V);
//灰度图 BINARY 二值化
threshold(gray, gray_B, 125, 255, THRESH_BINARY);
threshold(gray, gray_B_V, 125, 255, THRESH_BINARY_INV);
imshow("gray_B", gray_B);
imshow("gray_B_V", gray_B_V);
//灰度图像 TOZERO 变换
threshold(gray, gray_T, 125, 255, THRESH_TOZERO);
threshold(gray, gray_T_V, 125, 255, THRESH_TOZERO_INV);
imshow("gray_T", gray_T);
imshow("gray_T_V", gray_T_V);
//灰度图像 TRUNC 变换
threshold(gray, gray_TRUNC, 125, 255, THRESH_TRUNC);
imshow("gray_TRUNC", gray_TRUNC);
waitKey(0);
return 0;
}
结果:
1.7 THRESH_OTSU 和 THRESH_TRIANGLE
2.adaptiveThreshold函数
void cv::adaptiveThreshold(InputArray src, OutputArray dst, double maxValue,
int adaptiveMethod, int thresholdType, int blockSize, double C )
- src:待二值化的图像,图像只能是 CV_8UC1 数据类型。
- dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型。
- maxValue:二值化的最大值
- adaptiveMethod:自适应确定阈值的方法,分为均值法 ADAPTIVE_THRESH_MEAN_C和高斯法 ADAPTIVE_THRESH_GAUSSIAN_C 两种。
- thresholdType:选择图像二值化方法的标志,只能是 THRESH_BINARY 和 THRESH_BINARY_INV。
- blockSize:自适应确定阈值的像素邻域大小,一般为 3、5、7 的奇数。
- C:从平均值或者加权平均值中减去的常数,可以为正,也可以为负。
2.1代码示例(包含THRESH_OTSU 和 THRESH_TRIANGLE )
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
//灰度图像大津法和三角形法二值化
Mat img_Thr = imread("../pic/gril_2.png", IMREAD_GRAYSCALE);
double a ,b ,c,d ;
if (img_Thr.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
//cvtColor(img_Thr, img_Thr, COLOR_BGR2GRAY);
Mat img_Thr_O, img_Thr_O_1,img_Thr_T,img_Thr_T_1;
a = threshold(img_Thr, img_Thr_O, 100, 255, THRESH_BINARY | THRESH_OTSU);
b = threshold(img_Thr, img_Thr_T, 125, 255, THRESH_BINARY | THRESH_TRIANGLE);
c = threshold(img_Thr, img_Thr_O_1, 150, 255, THRESH_BINARY | THRESH_OTSU);
d = threshold(img_Thr, img_Thr_T_1, 200, 255, THRESH_BINARY | THRESH_TRIANGLE);
cout << "333 a =" <<a <<" b = " << b << endl;
cout << "333 c =" <<c <<" d = " << d << endl;
imshow("img_Thr", img_Thr);
imshow("img_Thr_O", img_Thr_O);
imshow("img_Thr_T", img_Thr_T);
imshow("img_Thr_O_1", img_Thr_O_1);
imshow("img_Thr_T_1", img_Thr_T_1);
//灰度图像自适应二值化
Mat adaptive_mean, adaptive_gauss;
adaptiveThreshold(img_Thr, adaptive_mean, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 255, 0);
adaptiveThreshold(img_Thr, adaptive_gauss, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 55, 0);
imshow("adaptive_mean", adaptive_mean);
imshow("adaptive_gauss", adaptive_gauss);
waitKey(0);
return 0;
}
结果:threshold函数不管设置的阈值是多少,只要有THRESH_OTSU 和 THRESH_TRIANGLE,就会重新匹配该照片的阈值