【opencv 450 Image Processing】Basic Thresholding Operations基本阈值操作

Goal

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

使用 OpenCV 函数 cv::threshold 执行基本阈值操作

Cool Theory

笔记

下面的解释属于 Bradski 和 Kaehler 的《Learning OpenCV》一书。 什么是

Thresholding?

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

 

Types of Thresholding

阈值类型

OpenCV 提供函数 cv::threshold 来执行阈值操作。

我们可以用这个函数实现 5 种类型的阈值操作。 我们将在以下小节中解释它们。

为了说明这些阈值处理是如何工作的,让我们考虑一个源图像,其中的像素具有强度值 src(x,y)。 下图描述了这一点。 水平蓝线表示阈值thresh(固定)。

 

Threshold Binary

阈值二值化处理

这个阈值操作可以表示为:

 

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

 

Threshold Binary, Inverted

阈值二值化,倒置

这个阈值操作可以表示为:

 

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

 

Truncate    (高于阈值的置为阈值,其余保留)

截断

这个阈值操作可以表示为:

 

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

 

Threshold to Zero   (低于阈值的置为0,其余保留)

该操作可以表示为:

 

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

 

Threshold to Zero, Inverted (高于阈值的置为0,其余保留)

该操作可以表示为:

 

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

 

Code

教程代码如下所示。 你也可以从这里下载https://github.com/opencv/opencv/tree/4.x/samples/cpp/tutorial_code/ImgProc/Threshold.cpp

#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using std::cout;
int threshold_value = 0;
int threshold_type = 3;
int const max_value = 255;
int const max_type = 4;
int const max_binary_value = 255;
Mat src, src_gray, dst;
const char* window_name = "Threshold Demo";
const char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted";
const char* trackbar_value = "Value";
static void Threshold_Demo( int, void* )
{
    /* 0: Binary
     1: Binary Inverted
     2: Threshold Truncated
     3: Threshold to Zero
     4: Threshold to Zero Inverted
    */
    threshold( src_gray, dst, threshold_value, max_binary_value, threshold_type );
    imshow( window_name, dst );
}
int main( int argc, char** argv )
{
    String imageName("stuff.jpg"); // by default
    if (argc > 1)
    {
        imageName = argv[1];
    }
    src = imread( samples::findFile( imageName ), IMREAD_COLOR ); // Load an image
    if (src.empty())
    {
        cout << "Cannot read the image: " << imageName << std::endl;
        return -1;
    }
    cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to Gray
    namedWindow( window_name, WINDOW_AUTOSIZE ); // Create a window to display results
    createTrackbar( trackbar_type,
                    window_name, &threshold_type,
                    max_type, Threshold_Demo ); // Create a Trackbar to choose type of Threshold
    createTrackbar( trackbar_value,
                    window_name, &threshold_value,
                    max_value, Threshold_Demo ); // Create a Trackbar to choose Threshold value
    Threshold_Demo( 0, 0 ); // Call the function to initialize
    waitKey();
    return 0;
}

Explanation

让我们检查一下程序的一般结构:

  1. 加载图像。 如果是 BGR,我们将其转换为灰度。 为此,请记住我们可以使用函数 cv::cvtColor
    String imageName("stuff.jpg"); // by default
    if (argc > 1)
    {
        imageName = argv[1];
    }
    src = imread( samples::findFile( imageName ), IMREAD_COLOR ); // Load an image
    if (src.empty())
    {
        cout << "Cannot read the image: " << imageName << std::endl;
        return -1;
    }
    cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to Gray
  1. 创建一个窗口来显示结果
namedWindow( window_name, WINDOW_AUTOSIZE ); // Create a window to display
  1. 为用户创建 2 个轨迹栏以输入用户输入:

Type of thresholding: Binary, To Zero, etc...

Threshold value

createTrackbar( trackbar_type,
                    window_name, &threshold_type,
                    max_type, Threshold_Demo ); // 创建一个跟踪栏以选择阈值类型    createTrackbar( trackbar_value,
                    window_name, &threshold_value,
                    max_value, Threshold_Demo ); // 创建一个 Trackbar 以选择阈值

  1. 等到用户输入阈值,阈值的类型(或直到程序退出)
  2. 每当用户更改任何 Trackbars 的值时,都会调用函数 Threshold_Demo(Java 中的更新):
static void Threshold_Demo( int, void* )
{
    /* 0: Binary
     1: Binary Inverted
     2: Threshold Truncated
     3: Threshold to Zero
     4: Threshold to Zero Inverted
    */
    threshold( src_gray, dst, threshold_value, max_binary_value, threshold_type );
    imshow( window_name, dst );
}

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

src_gray:我们的输入图像

dst:目标(输出)图像

threshold_value:进行阈值操作的阈值

max_BINARY_value:与二进制阈值操作一起使用的值(用于设置所选像素)

threshold_type:5 个阈值操作之一。 它们列在上面函数的注释部分。

Results

1.  编译此程序后,运行它,将图像的路径作为参数。 例如,对于输入图像:

 

2. 首先,我们尝试使用倒置的二进制阈值对我们的图像进行阈值处理。 我们预计比阈值亮的像素会变暗,这就是实际发生的情况,正如我们在下面的快照中看到的(从原始图像中注意到,与图像相比,小狗的舌头和眼睛特别亮,这 反映在输出图像中)。

 

3. 现在我们尝试将阈值设为零。 有了这个,我们期望最暗的像素(低于阈值)将完全变黑,而值大于阈值的像素将保持其原始值。 这通过以下输出图像的快照得到验证:

Now we try with the threshold to zero. With this, we expect that the darkest pixels (below the threshold) will become completely black, whereas the pixels with value greater than the threshold will keep its original value. This is verified by the following snapshot of the output image:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值