[OpenCV] 数字图像处理 C++ 学习——10基本阈值处理 附完整代码

前言

在数字图像处理领域,阈值处理是最基本、最常用的技术之一。阈值处理通过将图像的像素值与指定的阈值进行比较,将图像分割为前景和背景,从而突出图像中的重要特征。这种技术广泛应用于图像分割、目标检测、图像二值化等任务中。在本篇博客中,我们将详细介绍基本的阈值处理方法,包括简单阈值和自适应阈值,并通过代码示例展示如何在 OpenCV 中实现这些操作。

1.基本阈值处理类型

阈值处理是一种基于像素强度值的图像分割技术。通过设定一个或多个阈值,将图像分割为不同的区域。根据阈值的选择方法,阈值处理可以分为简单阈值处理和自适应阈值处理。

以下表格列出了 OpenCV 支持的各种阈值处理类型及其对应的公式和应用场景,帮助理解和选择合适的阈值处理方法。

Enumerator公式说明
THRESH_BINARY$ dst(x, y) = \begin{cases} \text{maxval}, & \text{if } src(x, y) > \text{thresh} \ 0, & \text{otherwise} \end{cases} $如果像素值大于阈值,则设置为最大值(通常是 255),否则设置为 0。
THRESH_BINARY_INV d s t ( x , y ) = { 0 , if  s r c ( x , y ) > thresh maxval , otherwise dst(x, y) = \begin{cases} 0, & \text{if } src(x, y) > \text{thresh} \\ \text{maxval}, & \text{otherwise} \end{cases} dst(x,y)={0,maxval,if src(x,y)>threshotherwiseTHRESH_BINARY 相反,如果像素值大于阈值,则设置为 0,否则设置为最大值。
THRESH_TRUNC$dst(x, y) = \begin{cases} \text{thresh}, & \text{if } src(x, y) > \text{thresh} \ src(x, y), & \text{otherwise} \end{cases} $将高于阈值的像素截断为阈值,其余保持不变。
THRESH_TOZERO$ dst(x, y) = \begin{cases} src(x, y), & \text{if } src(x, y) > \text{thresh} \ 0, & \text{otherwise} \end{cases}$保留高于阈值的像素值,其余设置为 0。
THRESH_TOZERO_INV$ dst(x, y) = \begin{cases} 0, & \text{if } src(x, y) > \text{thresh} \ src(x, y), & \text{otherwise} \end{cases}$THRESH_TOZERO 相反,保留低于阈值的像素值,其余设置为 0。
THRESH_MASK-用于掩码操作,通常在图像处理的特定区域应用阈值。
THRESH_OTSU-Otsu 算法自动选择最优阈值,适用于双峰直方图的图像。
THRESH_TRIANGLE-使用 Triangle 算法基于直方图的几何特征自动选择阈值。

(1)阈值二值化(binary)

如果像素值>指定的阈值,则设置为最大值(通常是 255);否则设置为 0。用于将图像分割成黑白两部分,即将前景和背景分离。

在这里插入图片描述

(2)阈值反二值化(binary_inv)

THRESH_BINARY 的反向版本。如果像素值大于阈值,则设置为 0;否则设置为最大值。用于需要反转前景和背景的场景。

在这里插入图片描述

(3)截断(truncate)

当像素值>指定的阈值时,将其设置为阈值;否则保持原来的像素值。这种方法将高于阈值的部分截断,常用于限制图像中的最大亮度。

在这里插入图片描述

(4)阈值取零(threshold to zero)

如果像素值>阈值,则保持原像素值;否则设置为 0。这种方法可以用于只保留图像中高于某一亮度的部分,其余部分设置为背景。
在这里插入图片描述

(5)阈值反取零(threshold to zero inverted)

THRESH_TOZERO 的反向版本。如果像素值>阈值,则设置为 0;否则保持原来的像素值。适用于需要反转高亮和低亮部分的场景。

在这里插入图片描述

(6)THRESH_MASK

这种模式通常用于掩码图像处理,限制阈值操作只影响某些区域。具体行为依赖于实际应用场景。

(7)THRESH_OTSU

Otsu 方法是一种自动确定图像阈值的算法,它根据图像的灰度分布自适应地选择最佳阈值。使用 Otsu 方法时,无需手动设置阈值,预设值可以为 0,最大值通常设为 255。例如:

threshold(grayImage, dst, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);

(8)THRESH_TRIANGLE

HRESH_TRIANGLE 方法是一种自适应的阈值选择方法。通过寻找图像灰度直方图中双峰之间的谷底来确定最佳阈值。这个方法特别适合具有双峰灰度分布的图像,因为它可以有效地分割图像中的前景和背景。

THRESH_TRIANGLE 方法对灰度直方图具有双峰特性的图像效果最佳。如果图像的灰度分布并不是双峰型的,那么该方法可能不理想。

2.代码实现

(1)图像读取

图片链接实验图片sherlock.jpg

先读取图像用于后面的操作

	cv::Mat image;
	image = imread("sherlock.jpg", IMREAD_GRAYSCALE);
	if (image.empty()) {
		printf("could not find the image...\n");
		return;
	}
	namedWindow("input image", cv::WINDOW_AUTOSIZE);
	namedWindow("Binary Image", WINDOW_AUTOSIZE);
	cv::imshow("input image", image);

(2)动态阈值处理和滑动条创建

定义了一个回调函数 on_trackbar,用于根据滑动条的位置实时更新二值化图像。通过 createTrackbar 函数创建的滑动条,可以动态调整阈值 thresholdValue,每次滑动条的值发生变化时,回调函数都会被调用,从而更新显示在窗口中的二值化图像。

// 回调函数,用于更新二值化图像
void on_trackbar(int, void* data) {
	Mat* image = static_cast<Mat*>(data);
	Mat binaryImage;
	//进行简单阈值处理
	cv::threshold(*image, binaryImage, thresholdValue, maxValue, THRESH_BINARY);
	//显示二值化图像
	cv::imshow("Binary Image", binaryImage);
}
createTrackbar("Threshold", "Binary Image", &thresholdValue, maxValue, on_trackbar, &image);
on_trackbar(thresholdValue, &image);

结果:

在这里插入图片描述

(3)自适应阈值处理1(Otsu)

THRESH_OTSU:使用 threshold 函数时,通过组合 THRESH_BINARY | THRESH_OTSU 标志,可以让 OpenCV 自动计算最佳阈值。

	// 使用 Otsu 阈值处理	
	cv::Mat otsuBinaryImage;
	double otsuThreshold = threshold(image, otsuBinaryImage, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("Otsu Binary Image", otsuBinaryImage);

在这里插入图片描述

(4)自适应阈值处理2(Triangle)

THRESH_TRIANGLE:类似地,通过 THRESH_BINARY | THRESH_TRIANGLE 标志,OpenCV 使用 Triangle 方法自动计算最佳阈值。

	// 使用 Triangle 阈值处理
	Mat triangleBinaryImage;
	// Triangle 方法通过寻找直方图中双峰之间的谷底来自动选择阈值
	double triangleThreshold = threshold(image, triangleBinaryImage, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
	imshow("Triangle Binary Image", triangleBinaryImage);

在这里插入图片描述

(5)自适应阈值处理3(adaptiveThreshold)

使用自适应阈值处理方法对图像进行二值化。cv::adaptiveThreshold 函数根据图像的局部区域动态计算阈值,使得在光照不均匀的情况下也能有效分割前景和背景。这里采用了高斯加权的方法 (ADAPTIVE_THRESH_GAUSSIAN_C) 和二值化类型 (THRESH_BINARY),结果显示在 “Adaptive Binary Image” 窗口中。

	cv::Mat adaptiveBinaryImage;
	int blockSize = 11;
	double C = 2;
	cv::adaptiveThreshold(image, adaptiveBinaryImage, maxValue, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, blockSize, C);
	cv::imshow("Adaptive Binary Image", adaptiveBinaryImage);

结果:
在这里插入图片描述

3.完整代码

#include<opencv2/opencv.hpp>
#include<highgui.hpp>

using namespace cv;
using namespace std;

int thresholdValue = 127;
int maxValue = 255;

// 回调函数,用于更新二值化图像
void on_trackbar(int, void* data) {
	Mat* image = static_cast<Mat*>(data);
	Mat binaryImage;
	//进行简单阈值处理
	cv::threshold(*image, binaryImage, thresholdValue, maxValue, THRESH_BINARY);
	//显示二值化图像
	cv::imshow("Binary Image", binaryImage);
}

void Basic_thresholds()
{
	cv::Mat image;
	image = imread("sherlock.jpg", IMREAD_GRAYSCALE);
	if (image.empty()) {
		printf("could not find the image...\n");
		return;
	}
	namedWindow("input image", cv::WINDOW_AUTOSIZE);
	namedWindow("Binary Image", WINDOW_AUTOSIZE);
	cv::imshow("input image", image);
	createTrackbar("Threshold", "Binary Image", &thresholdValue, maxValue, on_trackbar, &image);
	on_trackbar(thresholdValue, &image);
	cv::Mat adaptiveBinaryImage;
	int blockSize = 11;
	double C = 2;
	cv::adaptiveThreshold(image, adaptiveBinaryImage, maxValue, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, blockSize, C);
	cv::imshow("Adaptive Binary Image", adaptiveBinaryImage);
	waitKey(0);
}
int main() 
{
	Basic_thresholds();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mirror_zAI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值