在图像阈值化操作中,更关注的是从二值化图像中,分离目标区域和背景区域,但是仅仅通过设定固定阈值很难达到理想的分割效果。而自适应阈值,则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。这样做的好处:

1. 每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。

2. 亮度较高的图像区域的二值化阈值通常会较高,而亮度低的图像区域的二值化阈值则会相适应的变小。

3. 不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。

函数原型

.    void adaptiveThreshold(InputArray src, OutputArray dst,
. double maxValue, int adaptiveMethod,
. int thresholdType, int bolckSize, double C)

参数说明

参数1:InputArray类型的src,输入图像,填单通道,单8位浮点类型Mat即可。
参数2:函数运算后的结果存放在这。即为输出图像(与输入图像同样的尺寸和类型)。
参数3:预设满足条件的最大值。
参数4:指定自适应阈值算法。可选择ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C两种。(具体见下面的解释)。
参数5:指定阈值类型。可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
参数6:表示邻域块大小,用来计算区域阈值,一般选择为3、5、7......等。
参数7:参数C表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。(具体见下面的解释)。
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

对参数4与参数7内容的解释:
自适应阈值化计算大概过程是为每一个象素点单独计算的阈值,即每个像素点的阈值都是不同的,就是将该像素点周围B*B区域内的像素加权平均,然后减去一个常数C,从而得到该点的阈值。B由参数6指定,常数C由参数7指定。

ADAPTIVE_THRESH_MEAN_C,为局部邻域块的平均值,该算法是先求出块中的均值,再减去常数C。

ADAPTIVE_THRESH_GAUSSIAN_C,为局部邻域块的高斯加权和。该算法是在区域中(x, y)周围的像素根据高斯函数按照他们离中心点的距离进行加权计算,再减去常数C。

举个例子:如果使用平均值方法,平均值mean为190,差值delta(即常数C)为30。那么灰度小于160的像素为0,大于等于160的像素为255。如下图:

如果是反向二值化,如下图:

delta(常数C)选择负值也是可以的。

代码演示

/*
自适应阈值:adaptiveThreshold()函数
*/ #include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv; int main()
{
//------------【1】读取源图像并检查图像是否读取成功------------
Mat srcImage = imread("D:\\OutPutResult\\ImageTest\\build.jpg");
if (!srcImage.data)
{
cout << "读取图片错误,请重新输入正确路径!\n";
system("pause");
return -;
}
imshow("【源图像】", srcImage);
//------------【2】灰度转换------------
Mat srcGray;
cvtColor(srcImage, srcGray, CV_RGB2GRAY);
imshow("【灰度图】", srcGray);
//------------【3】初始化相关变量---------------
Mat dstImage; //初始化自适应阈值参数
const int maxVal = ;
int blockSize = ; //取值3、5、7....等
int constValue = ;
int adaptiveMethod = ;
int thresholdType = ;
/*
自适应阈值算法
0:ADAPTIVE_THRESH_MEAN_C
1:ADAPTIVE_THRESH_GAUSSIAN_C
--------------------------------------
阈值类型
0:THRESH_BINARY
1:THRESH_BINARY_INV
*/
//---------------【4】图像自适应阈值操作-------------------------
adaptiveThreshold(srcGray, dstImage, maxVal, adaptiveMethod, thresholdType, blockSize, constValue); imshow("【自适应阈值】", dstImage);
waitKey();
return ;
}

显示结果

可以发现自适应阈值能很好的观测到边缘信息。阈值的选取是算法自动完成的,很方便。

滤波处理

另外,做不做滤波处理等对图像分割影响也比较大。

1. adaptiveThreshold分割

    Mat img=imread("D:/ImageTest/sudoku.png",CV_LOAD_IMAGE_COLOR);
Mat dst1;
Mat dst2;
Mat dst3;
cv::cvtColor(img,img,COLOR_RGB2GRAY);//进行,灰度处理
medianBlur(img,img,);//中值滤波
threshold(img,dst1, , , THRESH_BINARY);//阈值分割
adaptiveThreshold(img,dst2,,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,,);//自动阈值分割,邻域均值
adaptiveThreshold(img,dst3,,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,,);//自动阈值分割,高斯邻域
//ADAPTIVE_THRESH_MEAN_C : threshold value is the mean of neighbourhood area
//ADAPTIVE_THRESH_GAUSSIAN_C : threshold value is the weighted sum of neighbourhood values where weights are a gaussian window.
imshow("dst1", dst1);
imshow("dst2", dst2);
imshow("dst3", dst3);
imshow("img", img);
waitKey();

效果对比,很明显加入邻域权重后处理更理想:

2. 加入滤波处理的最大类间方差分割

Mat img=imread("D:/ImageTest/pic2.png",CV_LOAD_IMAGE_COLOR);
Mat dst1;
Mat dst2;
Mat dst3;
cv::cvtColor(img,img,COLOR_RGB2GRAY);//进行,灰度处理
// medianBlur(img,img,5);
threshold(img,dst1, , , THRESH_BINARY);
threshold(img,dst2,, , THRESH_OTSU);//最大类间方差法分割 Otsu algorithm to choose the optimal threshold value
Mat img2=img.clone();
GaussianBlur(img2,img2,Size(,),);//高斯滤波去除小噪点
threshold(img2,dst3, , , THRESH_OTSU);
imshow("BINARY dst1", dst1);
imshow("OTSU dst2", dst2);
imshow("GaussianBlur OTSU dst3", dst3);
imshow("original img", img);
waitKey();

效果如下,显然不滤波和滤波差别明显:

参考文章:https://blog.csdn.net/sinat_36264666/article/details/77586964

https://blog.csdn.net/abcvincent/article/details/78822191

自适应阈值化操作:adaptiveThreshold()函数的更多相关文章

  1. 图像阈值化-threshold、adaptivethreshold

    在图像处理中阈值化操作,从一副图像中利用阈值分割出我们需要的物体部分(当然这里的物体可以是一部分或者整体).这样的图像分割方法是基于图像中物体与背景之间的灰度差异,而且此分割属于像素级的分割.open ...

  2. opencv2函数学习之threshold:实现图像阈值化

    在opencv2中,threshold函数可以进行阈值化操作. double threshold( const Mat& src, Mat& dst, double thresh,do ...

  3. OpenCV3编程入门笔记(4)腐蚀、膨胀、开闭运算、漫水填充、金字塔、阈值化、霍夫变换

    腐蚀erode.膨胀dilate 腐蚀和膨胀是针对图像中的白色部分(高亮部分)而言的,不是黑色的.除了输入输出图像外,还需传入模板算子element,opencv中有三种可以选择:矩形MORPH_RE ...

  4. OpenCV阈值化处理

    图像的阈值化就是利用图像像素点分布规律,设定阈值进行像素点分割,进而得到图像的二值图像.图像阈值化操作有多种方法,常用方法有经典的OTSU.固定阈值.自适应阈值.双阈值及半阈值化操作.这里对各种阈值化 ...

  5. opencv之图像阈值化处理

    一.函数简介 1.threshold-图像简单阈值化处理 函数原型:threshold(src, thresh, maxval, type, dst=None) src:图像矩阵 thresh:阈值 ...

  6. opencv python 图像二值化/简单阈值化/大津阈值法

    pip install matplotlib 1简单的阈值化 cv2.threshold第一个参数是源图像,它应该是灰度图像. 第二个参数是用于对像素值进行分类的阈值, 第三个参数是maxVal,它表 ...

  7. Vulkan移植GpuImage(一)高斯模糊与自适应阈值

    自适应阈值效果图 demo 这几天抽空看了下GpuImage的filter,移植了高斯模糊与自适应阈值的vulkan compute shader实现,一个是基本的图像处理,一个是组合基础图像处理聚合 ...

  8. 第十四节,TensorFlow中的反卷积,反池化操作以及gradients的使用

    反卷积是指,通过测量输出和已知输入重构未知输入的过程.在神经网络中,反卷积过程并不具备学习的能力,仅仅是用于可视化一个已经训练好的卷积神经网络,没有学习训练的过程.反卷积有着许多特别的应用,一般可以用 ...

  9. opencv —— threshold、adaptiveThreshold 固定阈值 & 自适应阈值 进行图像二值化处理

    阈值化 在对图像进行处理操作的过程中,我们常常需要对图像中的像素做出取舍与决策,直接剔除一些低于或高于一定值的像素. 阈值分割可以视为最简单的图像分割方法.比如基于图像中物体与背景之间的灰度差异,可以 ...

随机推荐

  1. BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)

    题意: 4种硬币买价值为V的商品,每种硬币有numi个,问有多少种买法 1000次询问,numi<1e5 思路: 完全背包计算出没有numi限制下的买法, 然后答案为dp[V]-(s1+s2+s ...

  2. Go语言实现:【剑指offer】表示数值的字符串

    该题目来源于牛客网<剑指offer>专题. 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2",&qu ...

  3. 05-Spring02-AOP

    今日知识 1. AOP 2. AspectJ 3. JdbcTemplate AOP 1. AOP :Aspect Oriented Programming,意为面向切面编程,通过预编译方式和运行期动 ...

  4. python xlrd操作

    python里面的xlrd模块详解(一)   那我就一下面积个问题对xlrd模块进行学习一下: 1.什么是xlrd模块? 2.为什么使用xlrd模块? 3.怎样使用xlrd模块? 1.什么是xlrd模 ...

  5. numpy 介绍与使用

    一.介绍 中文文档:https://www.numpy.org.cn/ NumPy是Python语言的一个扩展包.支持多维数组与矩阵运算,此外也针对数组运算提供大量的数学函数库.NumPy提供了与Ma ...

  6. 对CAN signal 的一点理解

      首先每个 ECU是一个网络节点,每个网络节点可收发一些 Message,每个Message 由CAN signals构成.每个 CAN signal利用一个或多个连续的2进制位来表示承载的信息.下 ...

  7. CentOS6.5安装指定的PHP版本(php5.5)(转)

    查询是否安装有php #rpm -qa|grep php 删除之前安装的php版本 (yum install 安装) #rpm -e php-fpm-5.3.3-47.el6.x86_64 --nod ...

  8. C#设计模式学习笔记:(11)享元模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7792973.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲结构型设计模式的第六个模式--享 ...

  9. 后端跨域的N种方法

    简单来说,CORS是一种访问机制,英文全称是Cross-Origin Resource Sharing,即我们常说的跨域资源共享,通过在服务器端设置响应头,把发起跨域的原始域名添加到Access-Co ...

  10. 剑指offer-面试题59_2-队列的最大值-队列

    /* 题目: 定义一个含max函数的队列类,并实现pop_front().push_back().max()函数. */ #include<iostream> #include<cs ...