OpenCV计算机图像视觉基础学习笔记7——基本阈值操作

阈值(Threshold)是什么?

阈的意思是界限,故阈值又叫临界值,是指一个效应能够产生的最低值或最高值。

——摘自百度百科“阈值”

图像阈值(Image Threshold)是什么?简单点说是把图像分割的标尺。简单用途,把图像根据不同的色域分成不同的区域。

(我就不信这次图床还不给过封面图)


阈值类型

阈值二值化(threshold binary),设定一个标线,超过此标线的按满处理,不足此标线的按0处理。

阈值反二值化(threshold binary inverted),设定一个标线,超过此标线的按0处理,不足此标线的按满处理。

截断(truncate),设定一个标线,超过此标线的取标线值,不足此标线的不动。

阈值取零(threshold to zero),设定一个标线,超过此标线的不动,不足此标线的按0处理。

阈值反取零(threshold to zero inverted),设定一个标线,超过此标线的按0处理,不足此标线的不动。

那么在OpenCV里,如何去确定使用什么阈值呢?其实已经给了相关的参数。

其中有两个比较特殊的THRESH_OTSUTHRESH_TRIANGLE,它们可以调用Otsu算法或Triangle算法对当前图片选择合适的阈值。
至于THRESH_MASK,我没查到这东西是干啥的,OpenCV社区中有回帖这么说:

obsolete constant? in opencv 2.2 (nov-2010) you can find THRESH_MASK https://github.com/opencv/opencv/blob… In opencv 4 it is defined but not used.

LBerger (Apr 15 ‘19)

然后我在GitHub里的源码中也没找到关于THRESH_MASK的有关信息。。。算了,不管他了

代码测试

先来测试阈值二值化的效果,看起来127的效果并不是很好,使用trackbar稍微调整了一下,192看起来还可以:

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
#include <opencv2/opencv.hpp>
#include <iostream>
#define debug cout << "ok" << endl;

using namespace cv;
using namespace std;

Mat src, gsrc, dst;
int thresholdval = 127;
int threshold_max = 255;
const char* input_title = "src image";
const char* output_title = "binary image";

void Threshold_Demo(int, void*) {
cvtColor(src, gsrc, CV_BGR2GRAY);
threshold(gsrc, dst, thresholdval, threshold_max, THRESH_BINARY);
imshow(output_title, dst);
}

int main() {
src = imread("D:/pics/lovelive.jpg");
if (!src.data) {
cout << "could not load image..." << endl;
return -1;
}
namedWindow(input_title, CV_WINDOW_AUTOSIZE);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(input_title, src);

createTrackbar("Threshold Value:", output_title, &thresholdval, threshold_max, Threshold_Demo);
Threshold_Demo(0, 0);

waitKey(0);
return 0;
}

再来测试一下阈值反二值化:

妈耶好恐怖。。。。还是192的时候看起来比较合适。

然后是截断、阈值取零、阈值反取零,来回调整还是有些麻烦,不如再借助一下trackbar让它能同时调整一下模式:

其实能用trackbar调整模式的原因是什么呢?可以尝试一下直接输出上表中那几个THRESH_打头的参数,你会发现它们其实就是0~4的整数值。

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
#include <opencv2/opencv.hpp>
#include <iostream>
#define debug cout << "ok" << endl;

using namespace cv;
using namespace std;

Mat src, gsrc, dst;
int thresholdval = 127;
int threshold_max = 255;
int type_value = 2;
int type_max = 4;
const char* input_title = "src image";
const char* output_title = "binary image";

void Threshold_Demo(int, void*) {
cvtColor(src, gsrc, CV_BGR2GRAY);
threshold(gsrc, dst, thresholdval, threshold_max, type_value);
imshow(output_title, dst);
}

int main() {
src = imread("D:/pics/lovelive.jpg");
if (!src.data) {
cout << "could not load image..." << endl;
return -1;
}
namedWindow(input_title, CV_WINDOW_AUTOSIZE);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(input_title, src);

createTrackbar("Threshold Value:", output_title, &thresholdval, threshold_max, Threshold_Demo);
createTrackbar("Type Value:", output_title, &type_value, type_max, Threshold_Demo);
Threshold_Demo(0, 0);

waitKey(0);
return 0;
}

刚才说到Otsu算法和Triangle算法,可以通过它进行调试,只需要将threshold(gsrc, dst, thresholdval, threshold_max, type_value);中的type_value换成THRESH_OTSU | type_value或者THRESH_TRIANGLE | type_value就可以。此时它会根据算法计算合适的阈值,这时拖动阈值滑块就无效了。


-------------本文结束,感谢您的阅读转载请注明原作者及出处-------------


本文标题:OpenCV计算机图像视觉基础学习笔记7——基本阈值操作

文章作者:Shawn Zhou

发布时间:2019年08月06日 - 10:08

最后更新:2019年08月07日 - 14:08

原始链接:http://shawnzhou.xyz/2019/08/06/19-08-06-01/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

知识无价,码字不易。对您有用,敬请打赏。金额随意,感谢关心。
0%