目录
1、图像阈值
2、阈值类型
3、代码演示
(1)图像阈值(threshold)含义:是将图像中的像素值划分为不同类别的一种处理方法。通过设定一个特定的阈值,将像素值与阈值进行比较,根据比较结果将像素分为两个或多个类别。
阈值 是什么?简单点说是把图像分割的标尺,这个标尺是根据什么产生的,阈值产生算法?阈值类型。(Binary segmentation)
(2)阈值的API
double threshold(
InputArray src, // 输入灰度图像
OutputArray dst, // 输出图像
double thresh, // 预设的阈值
double maxval, // 大于等于阈值的像素设置的最大值
int type // 阈值类型,将小于阈值的像素设置为0,大于等于阈值的像素设置为最大值。
);
需要注意的是,阈值的选择对于图像处理的效果非常重要,可以根据具体需求调整阈值的数值和阈值类型。另外,threshold函数还可以进行自适应阈值处理、Otsu阈值处理等更高级的图像分割方法。
(1)阈值二值化(threshold binary):
将图像分为两个类别,通常是将灰度图像转换为黑白图像。像素值小于等于阈值的被归为一类,大于阈值的被归为另一类。
左下方的图表示图像像素点Src(x,y)值分布情况,蓝色水平线表示阈值。
例子演示:(以二值化阈值为例)
假设有一幅灰度图像,像素值的范围是0到255。我们希望将图像中的目标物体分割出来,背景设置为黑色。
首先,选择一个合适的阈值,比如设定阈值为128。
对于每个像素,如果像素值<=128,则将其设置为黑色(0),否则设置为白色(255)。
重复上述步骤,对图像中的所有像素进行处理。
通过这个简单的二值化阈值处理,我们可以将图像中的目标物体与背景分离出来,得到一个二值图像,其中目标物体的像素值为白色,背景为黑色。
(2)阈值反二值化(threshold binary Inverted)
左下方的图表示图像像素点Src(x,y)值分布情况,蓝色水平线表示阈值。
(3)截断 (truncate)
左下方的图表示图像像素点Src(x,y)值分布情况,蓝色水平线表示阈值
(4)阈值取零 (threshold to zero)
左下方的图表示图像像素点Src(x,y)值分布情况,蓝色水平线表示阈值。
(5)阈值反取零(threshold to zero inverted)
左下方的图表示图像像素点Src(x,y)值分布情况,蓝色水平线表示阈值。
(6)THRESH_OTSU:标志来应用Otsu阈值处理。
Otsu方法是一种自动确定图像阈值的算法,它可以根据图像的灰度分布自适应地选择最佳阈值。
threshold(grayImage, dst, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
Otsu会自动进行阈值设置,所以预设值为0即可,最大为255.
(7)THRESH_TRIANGLE:标志进行阈值处理。
它可以根据图像的灰度分布自适应地选择最佳阈值。THRESH_TRIANGLE方法通过寻找直方图的双峰之间的谷底来确定阈值。
需要注意的是,THRESH_TRIANGLE方法适用于具有双峰灰度分布的图像,对于其他类型的图像效果可能不理想。因此,在使用THRESH_TRIANGLE阈值处理之前,建议先观察图像的灰度直方图,确保图像具有双峰特性。
总结:阈值分割有5种方法,阈值寻找有2种方法。
另外可以了解:
(1)多级化阈值:将图像分为多个类别,每个类别代表一种特定的像素强度范围。通常用于图像分割和物体识别任务。
(2)自适应阈值:根据图像局部区域的统计特征来确定阈值,使得不同区域具有相对合适的阈值。适用于图像 不均匀光照或对比度变化较大的情况。
(3)基于直方图的阈值:利用图像的直方图信息来确定阈值,如Otsu's方法、基于最大类间方差、基于最小错误率等。
(1)了解下createTrackbar,很实用一个接口。
createTrackbar是OpenCV中用于创建滑动条的函数。它可以在图像窗口中创建一个滑动条,通过滑动条来调整参数或阈值,实现实时交互。
int createTrackbar(
const String& trackbarname, // 滑动条的名称
const String& winname, // 滑动条所在的窗口名称
int* value, int count, // 初始值
TrackbarCallback onChange = 0, // 滑动条的最大值
void* userdata = 0 // 滑动条的回调函数);
(2)例子展示
#include
#include
#include
using namespace cv;
// 图像阈值
Mat src, gray_src, dst;
int threshold_value = 127;
int threshold_max = 255;
int type_value = 2;
int type_max = 4;
const char* input_title = "input image";
const char* output_title = "binary image";
void Threshold_Demo(int, void*);
int main(int argc, char** argv)
{
src = imread("test.jpg");
if (!src.data)
{
printf("could not load image...");
return -1;
}
namedWindow(input_title, CV_WINDOW_AUTOSIZE);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(input_title, src);
createTrackbar("Threshold Value:", output_title, &threshold_value, threshold_max, Threshold_Demo);
createTrackbar("Type Value:", output_title, &type_value, type_max, Threshold_Demo);
Threshold_Demo(0, 0);
waitKey(0);
return 0;
}
void Threshold_Demo(int, void*)
{
cvtColor(src, gray_src, CV_BGR2GRAY);
// 单纯阈值的二值化
// threshold(gray_src, dst, threshold_value, threshold_max, THRESH_BINARY);
//THRESH_OTSU去找阈值的话,就会忽略预设的阈值,所以为0即可,最大值是255
threshold(gray_src, dst, 0, 255, THRESH_OTSU | type_value);
imshow(output_title, dst);
}
效果展示: