2.預處理-二值化處理

阈值化操作在图像处理中是一种常用的算法,比如图像的二值化就是一种最常见的一种阈值化操作。opencv2和opencv3中提供了直接阈值化操作cv::threshold()和自适应阈值化操作cv::adaptiveThreshold()两种阈值化操作接口,这里将对这两个接口进行介绍和对比。

一、图像二值化基本原理

对灰度图像进行处理,设定阈值,在阈值中的像素值将变为1(白色部分),阈值为的将变为0(黑色部分)。

二、图像二值化处理步骤

(1)先对彩色图像进行灰度化

//img为原图,imgGray为灰度图
cvtColor(img, imgGray, CV_BGR2GRAY);
(2)对灰度图进行二值化

//imgGray为灰度图,result为二值图像
//100~255为阈值,可以根据情况设定
//在阈值中的像素点将变为0(白色部分),阈值之外的像素将变为1(黑色部分)。
threshold(imgGray, result, 100, 255, CV_THRESH_BINARY);
 

1、直接阈值化——cv::threshold()

阈值化操作的基本思想是,给定一个输入数组和一个阈值,数组中的每个元素将根据其与阈值之间的大小发生相应的改变。opencv3中支持这一操作的接口是cv::threshold(),具体调用方法如下:


double cv::threshold(
    cv::InputArray src, // 输入图像
    cv::OutputArray dst, // 输出图像
    double thresh, // 阈值
    double maxValue, // 向上最大值
    int thresholdType // 阈值化操作的类型 
);

如下表所示,每一种阈值化操作类型,对应着一种源图像上每一个像素点与阈值thresh之间比较操作。根据源图像像素和阈值之间的大小关系,目标像素可能被置为0、原像素值、或者设定的最大值maxValue。


下图将会帮助大家理解不同的阈值化类型所表示的确切含义。


void test_threshold()
{
    cv::Mat src = cv::imread("lena.jpg", cv::IMREAD_GRAYSCALE);
    cv::Mat dst;
 
    double thresh = 100;
    int maxVal = 255;
    cv::threshold(src, dst, thresh, maxVal, cv::THRESH_BINARY);
 
    cv::imshow("threshold", dst);
    cv::waitKey(0);
 
    return;
}


实用上面的代码进行阈值化处理,原图和五种不同方式阈值化的结果分别如下:

          

另外,在opencv3中cv::threshold()函数还支持一种特殊的阈值化操作方式,即Otsu算法。该算法的主要思想是,在进行阈值化时,考虑所有可能的阈值,分别计算低于阈值和高于阈值像素的方差,使下式最小化的值作为阈值:

其中,两类像素方差的权值由两类像素的个数决定。这种阈值化的结果相对来说比较理想,可以避免寻找合适阈值的操作,但是这种方式运算量较大,费时。处理的结果如下:

但是,直接阈值化操作是一种一刀切的方式,对于亮度分布差异较大的图像,常常无法找到一个合适的阈值。如下所示,对棋盘格进行二值化操作,由于图像右上角区域和图像下部的亮度差异较为大,无法找到一个合适的阈值,将棋盘上的所有棋盘格给区分开来。

 

 

针对于上述情况,我们需要一种改进的阈值化算法,即自适应阈值化。

2、自适应阈值化——cv::adaptiveThreshold()

自适应阈值化能够根据图像不同区域亮度分布的,改变阈值,具体调用方法如下:


void cv::adaptiveThreshold(
    cv::InputArray src, // 输入图像
    cv::OutputArray dst, // 输出图像
    double maxValue, // 向上最大值
    int adaptiveMethod, // 自适应方法,平均或高斯
    int thresholdType // 阈值化类型
    int blockSize, // 块大小
    double C // 常量
);

cv::adaptiveThreshold()支持两种自适应方法,即cv::ADAPTIVE_THRESH_MEAN_C(平均)和cv::ADAPTIVE_THRESH_GAUSSIAN_C(高斯)。在两种情况下,自适应阈值T(x, y)。通过计算每个像素周围bxb大小像素块的加权均值并减去常量C得到。其中,b由blockSize给出,大小必须为奇数;如果使用平均的方法,则所有像素周围的权值相同;如果使用高斯的方法,则(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。


测试代码如下:


void test_adaptive_threshold()
{
    cv::Mat src = cv::imread("chessboard.png", cv::IMREAD_GRAYSCALE);
    cv::Mat dst;
 
    int maxVal = 255;
    int blockSize = 41;
    double C = 0;
    cv::adaptiveThreshold(src, dst, maxVal, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, blockSize, C);
 
    cv::imshow("threshold", dst);
    cv::waitKey(0);
 
    return;
}


我们分别使用了平均和高斯两种自适应方法,结果如下:

  


--------------------- 
版权声明:本文为CSDN博主「PHILOS_THU」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/guduruyu/article/details/68059450

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值