图像处理旅行·在路上摄影

【图像处理】OpenCV系列二十 --- 二值化函数详解(thr

2019-05-03  本文已影响62人  307656af5a04

上一节我们学习了用自适应阈值对一幅图像进行二值化,相信大家学习之后,已经有所了解,本节我们针对二值化这个概念我们进入深入的剖析,本节我们将学习二值化函数(threshold)的具体原理与用法!

1、函数原型

double threshold(InputArray src, 
    OutputArray dst,
    double thresh, 
    double maxval, 
    int type);

2、函数功能
对数组元素进行固定阈值操作;并且该函数可以对多通道的数组用固定的阈值进行二值化;通常用于将灰度图像转换为二值化的图像;用于消除噪声,即滤除值过小或过大的像素;函数支持几种类型的阈值处理,由函数中的type参数决定;

另外,THRESH_OTSU or THRESH_TRIANGLE可以与type进行组合对图像进行二值化处理;在这些情况下,函数使用Otsu或者Triangle算法确定最优阈值,并使用它代替指定的阈值;

Note:
目前,Otsu或者Triangle算法仅支持8位单通道图像的实现,该函数支持就地操作哦!

返回值:
如果Otsu或者Triangle算法,则计算阈值。

3、参数详解

4、阈值类型详解

阈值详解

(1)THRESH_BINARY,正向二值化,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值设置为maxval;否则,将该点的像素值设置为0;
具体的公式如下

THRESH_BINARY

(2)THRESH_BINARY_INV ,反向二值化,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值设置为0;否则,将该点的像素值设置为maxval;
具体的公式如下

THRESH_BINARY_INV

(3)THRESH_TRUNC ,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值设置为threshold;否则,将该点的像素值不变;
具体的公式如下

THRESH_TRUNC

(4)THRESH_TOZERO ,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值不变;否则,将该点的像素值设置为0;
具体的公式如下

THRESH_TOZERO

(5)THRESH_TOZERO_INV ,如果当前的像素值大于设置的阈值(thresh),则将该点的像素值设置为0;否则,将该点的像素值不变;
具体的公式如下

THRESH_TOZERO_INV

(6)THRESH_MASK

(7)THRESH_OTSU,使用Otsu算法选择最佳阈值。

(8)THRESH_TRIANGLE,使用三角算法选择最佳阈值。

5、实验案例

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

using namespace cv;

// 原图像
Mat srcImage, dstImage;

// 调整阈值类型的变量
int g_ThresholdType = 0;
int g_ThresholdValue = 128;

// 回调函数
static void OnThresholdMethod(int, void*);


int main(int argc, char** argv)
{
    // 载入图像
    srcImage = imread("lena.png");

    // 判断图像是否为空
    if (srcImage.empty())
    {
        printf("image error!");
        return 0;
    }

    // 对原图像进行备份
    dstImage = srcImage.clone();

    namedWindow("原图");
    imshow("原图", dstImage);

    // 判断图像是彩色图像还是灰度图像
    // 如果图像是彩色图像,需要将图像转换为灰度图像
    if (srcImage.channels() == 3)
    {
        cvtColor(srcImage, srcImage, COLOR_BGR2GRAY);
    }

    namedWindow("【效果图】");

    createTrackbar("阈值大小:",
        "【效果图】",
        &g_ThresholdValue,
        255,
        OnThresholdMethod);

    createTrackbar("阈值类型:",
        "【效果图】",
        &g_ThresholdType,
        8,
        OnThresholdMethod);

    // 调用回调函数
    OnThresholdMethod(0, 0);

    waitKey(0);
    return 0;
}

void OnThresholdMethod(int, void*)
{
    Mat tmpImage = srcImage.clone();
    // 设置二值化的类型
    //目前,Otsu或者Triangle算法仅支持8位单通道图像的实现
    // 因此与这两个算法组合的时候,需要将图像转换为灰度图像
    if (g_ThresholdType==5)
    {
        if (srcImage.channels()==3)
            cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);       
        g_ThresholdType = THRESH_OTSU + THRESH_BINARY;
    }
    if (g_ThresholdType == 6)
    {
        if (srcImage.channels() == 3)
            cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
        g_ThresholdType = THRESH_OTSU + THRESH_BINARY_INV;
    }
    if (g_ThresholdType == 7)
    {
        if (srcImage.channels() == 3)
            cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
        g_ThresholdType = THRESH_TRIANGLE + THRESH_BINARY;
    }
    if (g_ThresholdType == 8)
    {
        if (srcImage.channels() == 3)
            cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
        g_ThresholdType = THRESH_TRIANGLE + THRESH_BINARY_INV;
    }

    // 二值化处理
    threshold(tmpImage,
        dstImage,
        g_ThresholdValue,
        255,
        g_ThresholdType);

    imshow("【效果图】", dstImage);
}

6、实验结果

原图 彩色图像正向二值化后效果图 彩色图像反向二值化后效果图 灰度图像正向二值化后效果图

好了,今天的OpenCV学到这里就结束了,本节二值化函数(threshold)讲的清晰,希望大家可以仔细的理解哦!!

我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C语言编程,C++语言编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!

上一篇下一篇

猜你喜欢

热点阅读