美文网首页图像处理旅行·在路上摄影
【图像处理】OpenCV系列二十 --- 二值化函数详解(thr

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

作者: 307656af5a04 | 来源:发表于2019-05-03 18:05 被阅读62次

    上一节我们学习了用自适应阈值对一幅图像进行二值化,相信大家学习之后,已经有所了解,本节我们针对二值化这个概念我们进入深入的剖析,本节我们将学习二值化函数(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、参数详解

    • 第一个参数,InputArray src,输入图像,可以是多通道图像、8位图像、32位浮点型图像;

    • 第二个参数,OutputArray dst,目标图像,和原图像有一样的尺寸、类型和同样的通道数;

    • 第三个参数,double thresh,进行二值化的阈值;

    • 第四个参数,double maxval,最大值,一般与THRESH_BINARY或者THRESH_BINARY_INV阈值类型一起使用;

    • 第五个参数,int type,阈值的类型;

    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对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/wssonqtx.html