0013-图像的阈值化-OTSU、固定阈值法、基于局部的阈值化

在图像处理中,我们通常会把图像先进行简化处理。其中图像的灰度化和图像的阈值化是最常用的两种简化处理方法。
图像的灰度化处理就是把图像从三维彩色空间降到一维的灰度空间,在OpenCV中实现起来很简单,用函数cvtColor就能实现。
图像的阈值化处理是在灰度图像的基础上,把灰度图像进一步简化为二值图像,即整幅图像的各点像素值只用两个数值来表示,其中一个数值为零,另一个数值为非零值。
图像的阈值化的关键是找到一个最佳阈值,使得在进行图像简化操作是尽量多的过滤掉我们不需要的信息并保留我们需要的信息。

本文介绍三种基于OpenCV的阈值化处理方法

第一种 OTSU阈值化(最大类间方差算法)
OTSU阈值化就是使用OTSU算法来计算出图像的最佳阈值,OTSU算法的原理这里暂时不叙述,需要的朋友可以去查阅相关资料!
OpenCV提供了threshold函数来实现OTSU算法
下面详细介绍threshold函数
threshold函数的C++原型如下:
C++: double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
参数意义介绍如下
src:输入阵列,要求是单通道的8位或32位的浮点数阵列
dst:输出阵列,和输入阵列的类型一样
thresh:阈值
maxval:阈值化后的非零值
type:阈值化类型,具体有哪些类型见下面的截图

除了上面截图中列出的五种类型,还有两种,如下
CV_THRESH_OTSU:函使用OTSU算法得到阈值来进行二值化图片,此时参数中的thresh不起作用
CV_THRESH_TRIANGLE:函使用三角算法得到阈值来进行二值化图片,此时参数中的thresh也不起作用


下面就给出使用threshold函数,并利用OTSU算法进行图像阈值化的源码
图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注!
源码中使用的图像下载链接:http://pan.baidu.com/s/1kUJMx1t 密码:r3d3

//opencv版本:OpenCV3.0
//VS版本:VS2013
//Author:qxsf321.net

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>    
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>

#include <iostream>

using namespace cv;
using namespace std;

int main()
{
        Mat img = imread("02.jpg");
        if (img.empty())
        {
                cout << "Error: Could not load image" << endl;
                return 0;
        }

        Mat gray;
        cvtColor(img, gray, CV_BGR2GRAY);

        Mat dst;
        threshold(gray, dst, 0, 255, CV_THRESH_OTSU);

        imshow("src", img);
        imshow("gray", gray);
        imshow("dst", dst);
        waitKey(0);

        return 0;
}

代码很简单,这里就不多作说明了。
程序运行结果如下图所示



第二种 固定阈值法
固定阈值法的阈值是固定的,即不用使用相关算法去计算这个阈值,而是由程序或用户设定。
我们在图像窗口中创建一个滑动条,通过滑动条去查看不同的阈值对应的阈值化后的图像。
源码如下

图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注!

源码中使用的图像下载链接:http://pan.baidu.com/s/1kUJMx1t 密码:r3d3
//opencv版本:OpenCV3.0
//VS版本:VS2013
//Author:qxsf321.net

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>    
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>

#include <iostream>

using namespace cv;
using namespace std;

void onChangeTrackBar(int pos, void* data)
{
        // 强制类型转换
        cv::Mat srcImage = *(cv::Mat*)(data);
        cv::Mat dstImage;
        // 根据滑动条的值进行二值化
        cv::threshold(srcImage, dstImage, pos, 255, 0);
        cv::imshow("dyn_threshold", dstImage);
}

int main()
{
        Mat img = imread("02.jpg");
        if (img.empty())
        {
                cout << "Error: Could not load image" << endl;
                return 0;
        }

        Mat gray;
        cvtColor(img, gray, CV_BGR2GRAY);

        namedWindow("dyn_threshold");

        imshow("dyn_threshold", gray);

        int value = 0;

    /* 创建滑动条createTrackbar,调用回调函数*/
        createTrackbar("pos", "dyn_threshold", &value, 255, onChangeTrackBar, &gray);
        waitKey(0);
        return 0;
}

代码说明
代码使用createTrackbar函数来创建一个滑动条,其原型和参数意义如下
int createTrackbar(const string& trackbarname, const string& winname,int* value, int count,  TrackbarCallback onChange = 0,  void* userdata = 0); 
trackbarname:滑动条上的变量名称;
winname:滑动条用于依附的图像窗口的名称;
value:滑动条上的变量指针;
count:滑动条上的变量的最大值,滑动条上变量的可取值范围为0~count;
onChange:回调函数名;
userdata:用户数据指针;
结合上面对各参数的叙述及源码,大家不难理解createTrackbar函数的使用。
程序运行的结果截图如下


这里我再提供一个程序运行结果的演示视频给大家
优酷网在线观看地址:http://v.youku.com/v_show/id_XMz ... m=a2hzp.8244740.0.0
大家在优酷网看视频的时候记得是可以选择高清模式的哦!
视频文件百度网盘下载及在线观看地址:http://pan.baidu.com/s/1miGCQ6W 密码:mrg6

第三种 基于局部的阈值化
OpenCV提供了adaptiveThreshold函数用来做图像基于局部的阈值化处理。
该方法的思路是把图像划分为许多小图像(小窗口),然后每个小图像做一个阈值化处理,阈值可以由两种算法算得,分别为ADAPTIVE_THRESH_MEAN_C和ADAPTIVE_THRESH_GAUSSIAN_C,即平均阈值算法和高斯阈值算法!
接下来,介绍下adaptiveThreshold函数,它的原型如下:
C++: void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)
参数意义介绍如下
src:源图像,要求是8位的单通道图像;
dst:输出图像;
maxValue:阈值化后的非零值;
adaptiveMethod:阈值计算方法,可选值为ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C;
thresholdType:阈值化类型,可选值为THRESH_BINARY or THRESH_BINARY_INV,具体的意义见下面这张图;

blockSize:计算局部阈值时的每个小窗口(每个局部)的大小,只能为奇数,最小值为3;
C:阈值偏移值,函数最终使用的阈值为使用adaptiveMethod计算出的阈值减去C。

基于局部的阈值化示例代码如下
图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注!
源码中使用的图像下载链接:http://pan.baidu.com/s/1kUJMx1t 密码:r3d3

//opencv版本:OpenCV3.0
//VS版本:VS2013
//Author:qxsf321.net

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>    
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>

#include <iostream>

using namespace cv;
using namespace std;

int main()
{
        Mat img = imread("02.jpg");
        if (img.empty())
        {
                cout << "Error: Could not load image" << endl;
                return 0;
        }

        Mat gray;
        cvtColor(img, gray, CV_BGR2GRAY);

        Mat dst;

        // 初始化自适应阈值参数
        int blockSize = 59;
        int constValue = 5;
        const int maxVal = 255;

        /* 自适应阈值算法
        0:ADAPTIVE_THRESH_MEAN_C
        1: ADAPTIVE_THRESH_GAUSSIAN_C */

        int adaptiveMethod = 0;

        /*阈值类型
        0: THRESH_BINARY
        1: THRESH_BINARY_INV */
        int thresholdType = 0;

        // 图像自适应阈值操作
        adaptiveThreshold(gray, dst, maxVal, adaptiveMethod, thresholdType, blockSize, constValue);

        imshow("src", img);
        imshow("gray", gray);
        imshow("dst", dst);
        waitKey(0);

        return 0;
}

运行结果截图如下


 

猜你喜欢

转载自blog.csdn.net/lehuoziyuan/article/details/84064352