opencv自带例子学习-灰度图像的阈值操作

首先,先看看阈值是个什么意思。百度百科上面的解释为

阈的意思是界限,故阈值又叫临界值,是指一个效应能够产生的最低值或最高值。此一名词广泛用于各方面,包括建筑学、生物学、飞行、化学、电信、电学、心理学等,如生态阈值

对应英文应该是threshold value.本次例子核心函数就名为threshold,函数里对应的阈值就是灰度图像的灰度值(也是亮度值)。所以可以知道,这是一个基于像素级别的图像处理函数。

下面直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* @file Threshold.cpp
* @brief Sample code that shows how to use the diverse threshold options offered by OpenCV
* @author OpenCV team
*/

/**
* 阈值
* 演示如何使用 OpenCV 提供的各种阈值选项的简短示例代码
*/

//头文件
#include "opencv2/imgproc.hpp" //图像处理相关
#include "opencv2/imgcodecs.hpp" //图像读取和写入相关
#include "opencv2/highgui.hpp" //GUI相关

/**
* 程序流程:
* 1、加载图像,命令行输入图像路径或者默认
* 2、初始化变量,创建窗口
* 3、创建滑动条
* 4、调用显示
*/


//命名空间
using namespace cv;

/// Global variables
// 全局变量
int threshold_value = 0; //阈值
int threshold_type = 3; //阈值分割的类型
int const max_value = 255; //最大值
int const max_type = 4; //最大值的类型
int const max_BINARY_value = 255; //二值化图像的最大值

// 图像变量, 窗口
Mat src, src_gray, dst;
const char* window_name = "Threshold Demo";

//滑动条
const char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted";
const char* trackbar_value = "Value";

/// Function headers
/// 回掉函数声明,原型必须为 void function_name(int, void*)
void Threshold_Demo( int, void* );

/**
* @function main
*/
// 主函数
int main( int argc, char** argv )
{
//! [load]
// 加载图像
String imageName("../data/stuff.jpg"); // by default, 默认路径
if (argc > 1)
{
imageName = argv[1];//或者命令行参数输入图像路径
}

//加载图像
src = imread( imageName, IMREAD_COLOR ); // Load an image

if( src.empty() )
{ return -1; }

//图像转为灰度图
cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to Gray
//! [load]

//! [window]
//创建窗口
namedWindow( window_name, WINDOW_AUTOSIZE ); // Create a window to display results
//! [window]

//! [trackbar]
// 创建滑动条
createTrackbar( trackbar_type,
window_name, &threshold_type,
max_type, Threshold_Demo ); // Create Trackbar to choose type of Threshold

createTrackbar( trackbar_value,
window_name, &threshold_value,
max_value, Threshold_Demo ); // Create Trackbar to choose Threshold value
//! [trackbar]

//调用显示
Threshold_Demo( 0, 0 ); // Call the function to initialize

/// Wait until user finishes program
/// 等待按下 esc 键退出
for(;;)
{
char c = (char)waitKey( 20 );
if( c == 27 )
{ break; }
}

}

//![Threshold_Demo]
/**
* @function Threshold_Demo
*/
void Threshold_Demo( int, void* )
{
/* 0: Binary
1: Binary Inverted
2: Threshold Truncated
3: Threshold to Zero
4: Threshold to Zero Inverted
*/

/**
* 阈值分割的类型
* 0、二进制,大于阈值, dst = max_value; 小于阈值, dst = 0;
* 1、反二进制,与二进制相反;
* 2、阈值截断,大于阈值, dst = thresh; 小于阈值, dst = src;
* 3、0阈值, 大于阈值, dst = src; 小于阈值, dst = 0;
* 4、反0阈值,与0阈值相反
*/

//调用阈值分割函数
threshold( src_gray, dst, threshold_value, max_BINARY_value,threshold_type );

imshow( window_name, dst );
}
//![Threshold_Demo]

/**
* 要点总结
* 阈值操作的类型,二进制、反二进制、阈值截断、0阈值、反0阈值
*/

代码注释的比较详细,主要来看看本例程的核心函数threshold()。函数的原型为

1
2
3
4
5
6
double cv::threshold ( InputArray  src, //输入图像
OutputArray  dst, //输出图像,即阈值操作处理后的图像,为只有黑白的二值图
double  thresh, //阈值,阈值操作的判断条件
double  maxval, //最大值,设定输出图像灰度的最大值
int  type  //阈值操作的方式类型
)

下面的来看看阈值操作都有哪些类型 threshold.png

image.png

很显然,整个函数的处理机制就是,将输入图像src(灰度图)的每个像素点与设定的阈值threshold比较,根据比较结果把像素点设置为0、maxval或者保留原灰度值。我们可以根据自己的需求选择不同的处理模式。设置不同int type的参数即可,该参数是一个枚举类型,图片中的THRESH_BINARY等对应着不同整数。

1
2
3
4
5
* 0、二进制,大于阈值, dst = max_value; 小于阈值, dst = 0;
* 1、反二进制,与二进制相反;
* 2、阈值截断,大于阈值, dst = thresh; 小于阈值, dst = src;
* 3、0阈值, 大于阈值, dst = src; 小于阈值, dst = 0;
* 4、反0阈值,与0阈值相反

不过建议不要使用整数图方便,直接选择变量名更好,程序可读性更强。

-------------本文结束感谢您的阅读-------------