OpenCV 4.12.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: 进行阈值操作的 \(thresh\) 值
  • max_BINARY_value: 用于二值阈值操作的值(用于设置选定的像素)
  • threshold_type: \(5\) 种阈值操作之一。它们列在上面函数的注释部分。

结果

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