Advertisement

OpenCV学习笔记(十一):阈值化:threshold(), adaptiveThreshold()

阅读量:

OpenCV学习笔记(十一):阈值化:threshold(),adaptivethreshold()

一、定义:

1)采用固定阈值的处理方式

复制代码
    double threshold(
    InputArray src,			// 输入图像,单通道
    OutputArray dst,		// 输出图像
    double thresh,			// 阈值的具体值
    double maxval,			// 最大值,生成二值图时用到
    int type);				// 阈值类型
    							// 常用的两种阈值化类型
    							// THRESH_BINARY     = 0, 阈值化处理生成二值图像
    							// THRESH_BINARY_INV = 1, 阈值化处理并反转生成二值图
    ==阈值类型:==
    0 = THRESH_BINARY二进制阈值化:
    将灰度值大于thresh的设置为maxval,不大于thresh设置为0。
    
    1 = THRESH_BINARY_INV反二进制阈值化:
    将灰度值大于thresh的设置为0,不大于thresh设置为maxval。
    
    2 = THRESH_TRUNC截断阈值化:
    将灰度值大于thresh的设置为threshold,不大于thresh的灰度值不变。
    
    3 = THRESH_TOZERO阈值化为0:
    将灰度值大于thresh的不变,超过阈值置为0。
    
    4 = THRESH_TOZERO_INV反阈值化为0:
    将灰度值大于thresh的不变,低于阈值置为0。
    
    THRESH_MASK
    
    THRESH_OTSU 使用Otsu算法选择最优阈值,使这个阈值可以将前景色和背景色尽可能分开。 
    
    THRESH_TRIANGLE 使用三角形算法选择最优阈值
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

2)自适应阈值处理过程

复制代码
    void adaptiveThreshold(
    InoutArray src, 		// 源图像数组
    OutputArray dst, 		// 输出图像组
    double maxValue, 		// 最大值,生成二值图时用到
    int adaptiveMethod, 	// 自适应阈值算法选择 ADAPTIVE_THRESH_MEAN_C或ADAPTIVE_THRESH_GAUSSIAN_C;
    int thresholdType, 		// 阈值类型THRESH_BINARY或THRESH_BINARY_INV
    int blockSize, 			// 邻域块大小,用来计算区域阈值,一般选择3、5、7……;
    double C				// 它是一个从均匀或加权均值提取的常数,可以是负数
    )
    
    ==自适应阈值算法==
    ADAPTIVE_THRESH_MEAN_C 的计算方法是
    计算出邻域的平均值再减去第七个参数double C的值
    
    ADAPTIVE_THRESH_GAUSSIAN_C 的计算方法是
    计算出邻域的高斯均匀值再减去第七个参数double C的值
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

二、固定阈值threshold() 代码示例:

1)核心控制函数

复制代码
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    using namespace std;
    
    int g_nThresholdValue1 = 124,g_nThresholdValue2=175;
    int g_nThresholdType = 0;				// 阈值类型 标识
    Mat g_srcImage,g_grayImage,g_dstImage,g_dstImage1,g_dstImage2;
    
    
    int main()
    {
    // 显示欢迎和帮助文字
    ShowHelpText( );
    
    // 1、读入源图片
    g_srcImage = imread("F:/C++/2. OPENCV 3.1.0/TEST/pellets.png");
    if(!g_srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
    imshow("原始图",g_srcImage);
    
    // 2、存留一份原图的灰度图
    cvtColor( g_srcImage, g_grayImage, COLOR_RGB2GRAY );
    
    // 3、创建窗口并显示原始图
    namedWindow( "【程序窗口】", WINDOW_AUTOSIZE );
    
    // 4、创建滑动条来控制阈值
    createTrackbar( "模式", "【程序窗口】", &g_nThresholdType,4, on_Threshold );
    createTrackbar( "min阈值1","【程序窗口】", &g_nThresholdValue1,255, on_Threshold );
    createTrackbar( "max阈值2","【程序窗口】", &g_nThresholdValue2,255, on_Threshold );
    
    // 5、初始化自定义的阈值回调函数
    on_Threshold( 0, 0 );
    
    // 6、轮询等待用户按键,如果ESC键按下则退出程序
    while(1)
    {
        int key;
        key = waitKey( 20 );
        if( (char)key == 27 ){ break; }
    }
    return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

2)统计该区间内所有像素点的数量:

复制代码
    int getWhitePixel(Mat& img)
    {
    int area=0;
    for(int i=0 ; i<img.rows ; i++)
        for(int j=0 ; j<img.cols ; j++)
            if(img.at<uchar>(i,j)==255)
                area ++;
    return area;
    
    //    int area=0;
    //    int rowNumber = img.rows;  //行数
    //    int colNumber = img.cols*img.channels();  //列数 x 通道数=每一行元素的个数
    //    //双重循环,遍历所有的像素值
    //    for (int i = 0; i < rowNumber; i++)  //行循环
    //    {
    //        uchar *data = img.ptr<uchar>(i);  //获取第i行的首地址
    //        for (int j = 0; j < colNumber; j++)
    //            if(data[j] ==255)
    //                area ++;
    //    }
    //    return area;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

3)区间阈值达成函数:

复制代码
    void on_Threshold( int, void* )
    {
    //调用阈值函数
    //CV_THRESH_BINARY          = 0,  /**< value = value > threshold ? max_value : 0         */
    //CV_THRESH_BINARY_INV   = 1,  /**< value = value > threshold ? 0 : max_value         */
    //CV_THRESH_TRUNC           = 2,  /**< value = value > threshold ? threshold : value    */
    //CV_THRESH_TOZERO		  = 3,  /**< value = value > threshold ? value : 0                */
    //CV_THRESH_TOZERO_INV  = 4,  /**< value = value > threshold ? 0 : value                */
    
    threshold(g_grayImage,g_dstImage1,g_nThresholdValue1,255,g_nThresholdType);    //    CV_THRESH_BINARY
    imshow( "threshold1", g_dstImage1 );
    threshold(g_grayImage,g_dstImage2,g_nThresholdValue2,255,g_nThresholdType);
    imshow( "threshold2", g_dstImage2 );
    // 两图相减 g_dstImage1-g_dstImage2=g_dstImage
    addWeighted(g_dstImage1,1.0,g_dstImage2,-1,0,g_dstImage);
    	
    	// 显示区间像素点数
    int area = getWhitePixel(g_dstImage);
    printf("\n 区间面积area =%d pixel",area);
    
    //更新效果图
    imshow( "【程序窗口】", g_dstImage );
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
复制代码
    static void ShowHelpText()
    {
    //输出一些帮助信息
    printf(	"\n\t欢迎来到【基本阈值操作】示例程序~\n\n");
    printf(	"\n\t按键操作说明: \n\n"
        "\t\t键盘按键【ESC】- 退出程序\n"
        "\t\t滚动条模式0- 二进制阈值\n"
        "\t\t滚动条模式1- 反二进制阈值\n"
        "\t\t滚动条模式2- 截断阈值\n"
        "\t\t滚动条模式3- 反阈值化为0\n"
        "\t\t滚动条模式4- 阈值化为0\n"  );
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
    
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

此处插入图片说明
Halcon的比较分析:

在这里插入图片描述

二、固定阈值threshold() 代码示例:

1)核心控制程序

复制代码
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    using namespace std;
    
    Mat g_srcImage, g_grayImage,g_matAdaptive;
    int g_nadaptiveMethod = ADAPTIVE_THRESH_MEAN_C;
    int g_C = 5;
    int g_blockSize=1;
    
    int main()
    {
     // 1、读入源图片
    g_srcImage = imread("F:/C++/2. OPENCV 3.1.0/TEST/pellets.png");
    if(!g_srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
    imshow("原始图",g_srcImage);
    
    // 2、存留一份原图的灰度图
    cvtColor( g_srcImage, g_grayImage, COLOR_RGB2GRAY );
    
    // 3、创建窗口并显示原始图
    namedWindow( "【自适应阈值分割】" , WINDOW_AUTOSIZE );
    
    // 4、创建滑动条来控制阈值
    createTrackbar( "阈值算法", "【自适应阈值分割】" , &g_nadaptiveMethod,1, on_Threshold );
    createTrackbar( "领域尺寸","【自适应阈值分割】" , &g_blockSize,9, on_Threshold );
    createTrackbar( "常数 C","【自适应阈值分割】" , &g_C,255, on_Threshold );
    
    // 5、初始化自定义的阈值回调函数
    on_Threshold( 0, 0 );
    
    // 6、轮询等待用户按键,如果ESC键按下则退出程序
    while(1)
    {
        int key;
        key = waitKey( 20 );
        if( (char)key == 27 ){ break; }
    }
    return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
复制代码
    void on_Threshold( int, void* )
    {	
    	// 自适应阈值分割
    adaptiveThreshold(g_grayImage, g_matAdaptive, 255, g_nadaptiveMethod, THRESH_BINARY_INV, 2*g_blockSize+1, g_C);
    // 更新效果图
    imshow( "【自适应阈值分割】" , g_matAdaptive );
    }
    
    
      
      
      
      
      
      
      
    
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

全部评论 (0)

还没有任何评论哟~