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

news/2025/1/16 1:34:40/

文章目录

  • 前言
  • 1.基本阈值处理类型
    • (1)阈值二值化(binary)
    • (2)阈值反二值化(binary_inv)
    • (3)截断(truncate)
    • (4)阈值取零(threshold to zero)
    • (5)阈值反取零(threshold to zero inverted)
    • (6)THRESH_MASK
    • (7)THRESH_OTSU
    • (8)THRESH_TRIANGLE
  • 2.代码实现
    • (1)图像读取
    • (2)动态阈值处理和滑动条创建
    • (3)自适应阈值处理1(Otsu)
    • (4)自适应阈值处理2(Triangle)
    • (5)自适应阈值处理3(adaptiveThreshold)
  • 3.完整代码

前言

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

http://www.ppmy.cn/news/1521327.html

相关文章

OpenHarmony轻松玩转GIF数据渲染

OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;提供了Image组件支持GIF动图的播放&#xff0c;但是缺乏扩展能力&#xff0c;不支持播放控制等。今天介绍一款三方库——ohos-gif-drawable三方组件&#xff0c;带大家一起玩转GIF的数据渲染&#xff0c;搞…

cad打印pdf很模糊怎么调清晰?2024教你快速进行文件格式转换方法合集

cad打印pdf很模糊怎么调清晰&#xff1f;2024教你快速进行文件格式转换方法合集 在使用CAD打印PDF时&#xff0c;输出的PDF文件如果模糊&#xff0c;通常是因为打印设置或者导出参数不正确。以下是五款软件和工具&#xff0c;能够帮助你调整CAD打印时的输出设置&#xff0c;从…

Qt 应用程序主界面

主要窗口类的概述 这些类提供了典型现代主应用程序窗口所需的一切&#xff0c;如主窗口本身、菜单和工具栏、状态栏等。 QAction 可以插入小部件的抽象用户界面操作 QActionGroup 将动作组合在一起 QDockWidget 小部件&#xff0c;可以停靠在QMainWindow中&#xff0c;也可以作…

黑马程序员Python数据挖掘|1Jupyter Notebook的使用

一 Jupyter Notebook介绍 二 为什么用Jupyter Notebook 1.在画图方面的优势 用 Jupyter Notebook &#xff1a; 方便进行数据的展示。 用 pycharm : 画完图后没有继续执行读取数据的代码&#xff0c;阻塞了。 把图片关掉才会继续执行代码。 2.在pycharm里如果读取很大的数据&…

优化器与现有网络模型的修改

一、优化器 optimizer optim.SGD(model.parameters(), lr0.01&#xff08;学习速率&#xff09;, momentum0.9) optimizer optim.Adam([var1, var2], lr0.0001) 一般&#xff0c;学习率的设置&#xff0c;先从大的设置&#xff0c;逐渐变小。 神经网络可以参见上篇文章&am…

oceanbase OBCE 第四章实验 事务与远程执行

实验环境&#xff1a;企业版V3 1-1-1 前期准备&#xff1a; 新建一个 oracle 租户 1C2GB 新建资源规格&#xff1a; create resource unit u1_ora max_cpu1,min_cpu1,max_memory2G,min_memory2G,max_iops128,max_disk_size10G,max_session_num100; 新建资源池&#xff1a; c…

【AI】 代码界的超级加速器!阿里云通义灵码让你工作效率飙升,编程就像开了挂一样!

文章目录 一、正文&#xff1a;二、核心场景代码智能生成研发智能问答 三、功能介绍行间代码生成研发智能问答编码问题解决企业级管理 结语相关链接&#xff1a; 一、正文&#xff1a; 在当今快节奏的软件开发领域&#xff0c;提高工作效率是每一位开发者不断追求的目标。 通义…

Vue:F11全屏模式状态监听,识别

本文将介绍如何在vue中实现按F11键后全屏模式的监听。 来回切换F11之后,控制台打印结果如下图所示, <script lang="ts" setup>import {ref, onMounted, onBeforeUnmount } from vue;