OpenCV 4.11.0
开源计算机视觉库
加载中…
搜索中…
未找到匹配项
基本的阈值操作

上一篇教程: 图像金字塔
下一篇教程: 使用 inRange 的阈值操作

原作者Ana Huamán
兼容性OpenCV >= 3.0

目标

在本教程中,您将学习如何

酷炫理论

注意
下面的解释来自 Bradski 和 Kaehler 合著的书籍 Learning OpenCV。什么是

阈值化?

  • 最简单的分割方法
  • 应用示例:分离图像中对应于我们想要分析的对象的区域。这种分离是基于对象像素和背景像素之间的强度变化。
  • 为了将我们感兴趣的像素与其余像素(最终将被拒绝)区分开来,我们执行每个像素强度值相对于阈值(根据要解决的问题确定)的比较。
  • 一旦我们正确地分离出重要的像素,我们就可以用确定的值来设置它们以识别它们(例如,我们可以为它们分配值 \(0\)(黑色)、\(255\)(白色)或任何适合您需求的值)。

阈值化的类型

  • OpenCV 提供了函数 cv::threshold 来执行阈值操作。
  • 我们可以使用此函数执行 \(5\) 种类型的阈值操作。我们将在以下小节中解释它们。
  • 为了说明这些阈值处理过程是如何工作的,让我们考虑一下我们有一个源图像,其像素具有强度值 \(src(x,y)\)。下图描述了这一点。水平蓝线表示阈值 \(thresh\)(固定)。

二值阈值化

  • 此阈值操作可以表示为

    \[\texttt{dst} (x,y) = \fork{\texttt{maxVal}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\]

  • 因此,如果像素 \(src(x,y)\) 的强度高于 \(thresh\),则新像素强度设置为 \(MaxVal\)。否则,像素设置为 \(0\)。

反二值阈值化

  • 此阈值操作可以表示为

    \[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxVal}}{otherwise}\]

  • 如果像素 \(src(x,y)\) 的强度高于 \(thresh\),则新像素强度设置为 \(0\)。否则,它设置为 \(MaxVal\)。

截断阈值化

  • 此阈值操作可以表示为

    \[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\]

  • 像素的最大强度值为 \(thresh\),如果 \(src(x,y)\) 更大,则其值将被截断。见下图

阈值化为零

  • 此操作可以表示为

    \[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\]

  • 如果 \(src(x,y)\) 低于 \(thresh\),则新像素值将设置为 \(0\)。

反阈值化为零

  • 此操作可以表示为

    \[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\]

  • 如果 \(src(x,y)\) 大于 \(thresh\),则新像素值将设置为 \(0\)。

代码

解释

让我们检查程序的总体结构

  • 加载图像。如果是 BGR,则将其转换为灰度。为此,请记住我们可以使用函数 cv::cvtColor
  • 创建一个窗口来显示结果
  • 创建 2 个轨迹条供用户输入用户输入
    • 阈值类型:二进制、到零等……
    • 阈值
  • 等待用户输入阈值、阈值类型(或程序退出)
  • 每当用户更改任何轨迹条的值时,都会调用函数 *Threshold_Demo*(Java 中的 *update*)

如您所见,调用了函数 cv::threshold。我们在 C++ 代码中提供了 5 个参数

  • *src_gray*:我们的输入图像
  • *dst*:目标(输出)图像
  • *threshold_value*:进行阈值操作的阈值
  • *max_BINARY_value*:用于二进制阈值操作的值(用于设置选定的像素)
  • *threshold_type*:5 个阈值操作之一。它们列在上面函数的注释部分。

结果

  1. 编译此程序后,运行它并给出图像路径作为参数。例如,对于输入图像为
  1. 首先,我们尝试使用 *反向二值阈值* 对图像进行阈值处理。我们预计亮度高于阈值的像素将变暗,这实际上就是发生的情况,如下图所示(注意从原始图像中,狗的舌头和眼睛与图像相比特别明亮,这反映在输出图像中)。
  1. 现在我们尝试使用 *阈值到零*。这样,我们预计最暗的像素(低于阈值)将完全变黑,而值大于阈值的像素将保持其原始值。这通过以下输出图像快照得到验证