仅自学做笔记用,后续有错误会更改
参考文章:https://blog.csdn.net/qq_37835727/article/details/123373339
理论
-
图像阈值:什么是图像阈值?简单点来说就是把图像分割的标尺, 举个栗子, 现在想象一个场景, 一个桌子上有一堆苹果, 现在要求你去将它分为两类, 我们很容易就想到, 把大的划到一边, 小的划到另一边, 那么这个划分大小的标准,具体到某个值, 就是我们所说的阈值, 它是一个划分的标尺。
-
阈值类型 - 阈值二值化(threshold binary): 大于阈值的直接赋为最大值(255), 小于阈值的赋为最小值(0)
图示:
-
阈值类型 - 阈值反二值化(threshold binary Inverted): 大于阈值的直接赋为最小值(0), 小于阈值的赋为最大值(255)
图示:
-
阈值类型 - 截断(truncate) : 超过阈值的部分, 赋值为阈值
图示:
-
阈值类型 - 阈值取零(threshold to zero): 大于阈值部分不变, 小于阈值部分取零
图示:
-
阈值类型 - 阈值反取零(threshold to zero inverted): 大于阈值部分取零, 小于阈值部分不变
图示:
-
上边几个除了手动输入阈值外, opencv中还提供了两个方法自动帮你找阈值:
- THRESH_OTSU : 原理是基于类内最小方差实现阈值寻找
- THRESH_TRIANGLE: 三角算法,原理如图:
相关API
threshold(Mat src, Mat dst, int value, int max, int type)
- 参数1:原图数据
- 参数2:输出图像数据
- 参数3:像素阈值
- 参数4:像素最大值
- 参数5:阈值操作类型, 可选
THRESH_BINARY
THRESH_BINARY_INV
THRESH_TRUNC
THRESH_TOZERO
THRESH_TOZERO_INV
THRESH_OTSU
THRESH_TRIANGLE
代码示例
using namespace cv;
Mat src, gray_src, dst;
// 这次直接定义两个滑块值, 一个拖动改变阈值, 一个拖动改变阈值类型, 方便切换查看
int threshold_value = 127; //初始默认阈值
int threshold_max = 255;
int type_value = 2; // 初始默认阈值类型
int type_max = 4; //阈值类型的最大值,从0~4依次是:THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV
const char* output_title = "binary image";
void Threshold_Demo(int, void*);
int main(int argc, char** argv){
src = imread(...);
if( !src.data ){
printf(" could not load image...\n ");
return -1;
}
// 照样的, 先显示原图
namedWindow("input_image", CV_WINDOW_AUTOSIZE);
imshow("input_image", src);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
createTrackbar("Threshold Value:", output_title, &threshold_value, threshold_max, Threshold_Demo);
createTrackbar("Type Value:", output_title, &type_value, type_max, Threshold_Demo);
Treshold_Demo(0, 0);
waitKey(0);
return 0;
}
void Threshold_Demo(int, void*){
//先转为灰度图, 必须有这一步,因为opencv自带接口的阈值操作都是在8位灰度图上操作, 没有这一步程序会直接崩溃
cvtColor(src, gray_src, CV_BGR2GRAY);
//再进行阈值操作,其中threshold_value, type_value都是通过滑块动态调整的
threshold(gray_src, dst, threshold_value, threshold_max, type_value);
//以下两行代码代表用opencv自动帮你计算阈值,使用这俩就表示threshold_value的值已经无效了,随便你拖动改变值, 它都不会 使用, 只使用它最后计算出来的值
//threshold(gray_src, dst, threshold_value, threshold_max, THRESH_OTSU | type_value);
//threshold(gray_src, dst, threshold_value, threshold_max, THRESH_TRIANGLE | type_value);
imshow(output_title, dst);
}
效果截图(注意图片上两个可拖动的滑块值的变动):
THRESH_BINARY(二值化)效果:
THRESH_BINARY_INV(反二值化)效果:
THRESH_TRUNC(截断)效果:
THRESH_TOZERO(取零)效果:
THRESH_TOZERO_INV(反取零)效果: