前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【从零学习OpenCV 4】图像二值化

【从零学习OpenCV 4】图像二值化

作者头像
小白学视觉
发布于 2019-11-27 03:04:07
发布于 2019-11-27 03:04:07
99800
代码可运行
举报
运行总次数:0
代码可运行

经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。

我们在上一节程序中生成了一张只有黑色和白色的图像,这种“非黑即白”的图像像素的灰度值无论在什么数据类型中只有最大值和最小值两种取值,因此称其为二值图像。二值图像色彩种类少,可以进行高度的压缩,节省存储空间,将非二值图像经过计算变成二值图像的过程称为图像的二值化。在OpenCV 4中提供了threshold()和adaptiveThreshold()两个函数用于实现图像的二值化,我们首先介绍threshold()函数的使用方法,该函数的函数原型在代码清单3-17中给出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
代码清单3-17 threshold()函数原型
1.  double cv::threshold(InputArray src,
2.                         OutputArray dst,
3.                         double  thresh,
4.                         double  maxval,
5.                         int  type
6.                         )
  • src:待二值化的图像,图像只能是CV_8U和CV_32F两种数据类型。对于图像通道数目的要求和选择的二值化方法相关。
  • dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型和通道数。
  • thresh:二值化的阈值。
  • maxval:二值化过程的最大值,此函数只在THRESH_BINARY和THRESH_BINARY_INV两种二值化方法中才使用,但是在使用其他方法是也需要输入。
  • type:选择图像二值化方法的标志。

该函数是众多二值化方法的集成,所有的方法都实现了一个功能,就是给定一个阈值,计算所有像素灰度值与这个阈值关系,得到最终的比较结果。函数中有些阈值比较方法输出结果的灰度值并不是二值的,而是具有一个取值范围,不过为了体现其最常用的功能,我们仍然称其为二值化函数或者阈值比较函数。函数的部分参数和返回值都是针对特定的算法才有用,但是即使不使用这些算法在使用函数时也需要明确的给出,不可缺省。函数的最后一个参数是选择二值化计算方法的标志,可以选择二值化方法以及控制哪些参数对函数的计算结果产生影响,该标志可以选择的范围及含义在表3-2中给出。

表3-2 二值化方法可选择的标志及含义

标志参数

简记

作用

THRESH_BINARY

0

灰度值大于阈值为最大值,其他值为0

THRESH_BINARY_INV

1

灰度值大于阈值为0,其他值为最大值

THRESH_TRUNC

2

灰度值大于阈值的为阈值,其他值不变

THRESH_TOZERO

3

灰度值大于阈值的不变,其他值为0

THRESH_TOZERO_INV

4

灰度值大于阈值的为零,其他值不变

THRESH_OTSU

8

大津法自动寻求全局阈值

THRESH_TRIANGLE

16

三角形法自动寻求全局阈值

接下来将详细的介绍每种标志对应的二值化原理和需要的参数。

1

01

THRESH_BINARY和THRESH_BINARY_INV

这两个标志是相反的二值化方法,THRESH_BINARY是将灰度值与阈值(第三个参数thresh)进行比较,如果灰度值大于阈值就将灰度值改为函数中第四个参数maxval的值,否则将灰度值改成0。THRESH_BINARY_INV标志正好与这个过程相反,如果灰度值大于阈值就将灰度值改为0,否则将灰度值改为maxval的值。这两种标志的计算公式在式(3.7)中给出。

(3.7)

1

02

THRESH_TRUNC

这个标志相当于重新给图像的灰度值设定一个新的最大值,将大于新的最大值的灰度值全部重新设置为新的最大值,具体逻辑为将灰度值与阈值thresh进行比较,如果灰度值大于thresh则将灰度值改为thresh,否则保持灰度值不变。这种方法没有使用到函数中的第四个参数maxval的值,因此maxval的值对本方法不产生影响。这种标志的计算公式在式(3.8)中给出。

(3.8)

1

03

THRESH_TOZERO和THRESH_TOZERO_INV

这两个标志是相反的阈值比较方法, THRESH_TOZERO表示将灰度值与阈值thresh进行比较,如果灰度值大于thresh则将保持不变,否则将灰度值改为0。THRESH_TOZERO_INV方法与其相反,将灰度值与阈值thresh进行比较,如果灰度值小于等于thresh则将保持不变,否则将灰度值改为0。这种两种方法都没有使用到函数中的第四个参数maxval的值,因此maxval的值对本方法不产生影响。这两个标志的计算公式在式(3.9)中给出。

(3.9)

前面五种标志都支持输入多通道的图像,在计算时分别对每个通道进行阈值比较。为了更加直观的理解上述阈值比较方法,我们假设图像灰度值是连续变化的信号,将阈值比较方法比做滤波器,绘制连续信号通过滤波器后的信号形状,结果如图3-14所示,图中红线为设置的阈值,黑线为原始信号通过滤波器后的信号形状。

图3-14 上述5种阈值比较法的信号示意图

1

04

THRESH_OTSU和THRESH_TRIANGLE

这两种标志是获取阈值的方法,并不是阈值的比较方法的标志,这两个标志可以和前面5种标志一起使用,例如“THRESH_BINARY| THRESH_OTSU”。前面5种标志在调用函数时都需要人为的设置阈值,如果对图像不了解设置的阈值不合理,会对处理后的效果造成严重的影响,这两个标志分别表示利用大津法(OTSU)和三角形法(TRIANGLE)结合图像灰度值分布特性获取二值化的阈值,并将阈值以函数返回值的形式给出。因此如果函数最后一个参数设置了这两个标志中的任何一个,那么函数第三个参数thresh将由系统自动给出,但是在调用函数的时候仍然不能缺省,只是程序不会使用这个数值。需要注意的是,目前为止OpenCV 4中针对这两个标志只支持输入CV_8UC1类型的图像。

threshold()函数全局只使用一个阈值,在实际情况中由于光照不均匀以及阴影的存在,全局只有一个阈值会使得在阴影处的白色区域也会被函数二值化成黑色,因此adaptiveThreshold()函数提供了两种局部自适应阈值的二值化方法,该函数的函数原型在代码清单3-18中给出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
代码清单3-18 adaptiveThreshold()函数原型
1.  void cv::adaptiveThreshold(InputArray src,
2.                                OutputArray dst,
3.                                double  maxValue,
4.                                int  adaptiveMethod,
5.                                int  thresholdType,
6.                                int  blockSize,
7.                                double   C
8.                                   )
  • src:待二值化的图像,图像只能是CV_8UC1数据类型。
  • dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型。
  • maxValue:二值化的最大值。
  • adaptiveMethod:自制应确定阈值的方法,分为均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_C这两种。
  • thresholdType:选择图像二值化方法的标志,只能是THRESH_BINARY和THRESH_BINARY_INV。
  • blockSize:自适应确定阈值的像素邻域大小,一般为3,5,7的奇数。
  • C:从平均值或者加权平均值中减去的常数,可以为正,也可以为负。

该函数将灰度图像转换成二值图像,通过均值法和高斯法自适应的计算blockSize* blockSize邻域内的阈值,之后进行二值化,其原理与前面的相同,这里就不再赘述。

为了直观的体会到图像二值化的效果,在代码清单3-19中给出了分别对彩色图像和灰度图像进行二值化的示例程序,程序运行结果在图3-15、图3-16中给出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
代码清单3-19 myThreshold.cpp图像二值化
1.  #include <opencv2\opencv.hpp>
2.  #include <iostream>
3.  #include <vector>
4.  
5.  using namespace std;
6.  using namespace cv;
7.  
8.  int main()
9. {
10.    Mat img = imread("lena.png");
11.    if (img.empty())
12.    {
13.      cout << "请确认图像文件名称是否正确" << endl;
14.      return -1;
15.    }
16.  
17.    Mat gray;
18.    cvtColor(img, gray, COLOR_BGR2GRAY);
19.    Mat img_B, img_B_V, gray_B, gray_B_V, gray_T, gray_T_V, gray_TRUNC;
20.  
21.    //彩色图像二值化
22.    threshold(img, img_B, 125, 255, THRESH_BINARY);
23.    threshold(img, img_B_V, 125, 255, THRESH_BINARY_INV);
24.    imshow("img_B", img_B);
25.    imshow("img_B_V", img_B_V);
26.  
27.    //灰度图BINARY二值化
28.    threshold(gray, gray_B, 125, 255, THRESH_BINARY);
29.    threshold(gray, gray_B_V, 125, 255, THRESH_BINARY_INV);
30.    imshow("gray_B", gray_B);
31.    imshow("gray_B_V", gray_B_V);
32.  
33.    //灰度图像TOZERO变换
34.    threshold(gray, gray_T, 125, 255, THRESH_TOZERO);
35.    threshold(gray, gray_T_V, 125, 255, THRESH_TOZERO_INV);
36.    imshow("gray_T", gray_T);
37.    imshow("gray_T_V", gray_T_V);
38.  
39.    //灰度图像TRUNC变换
40.    threshold(gray, gray_TRUNC, 125, 255, THRESH_TRUNC);
41.    imshow("gray_TRUNC", gray_TRUNC);
42.  
43.    //灰度图像大津法和三角形法二值化
44.    Mat img_Thr = imread("threshold.png", IMREAD_GRAYSCALE);
45.    Mat img_Thr_O, img_Thr_T;
46.    threshold(img_Thr, img_Thr_O, 100, 255, THRESH_BINARY | THRESH_OTSU);
47.    threshold(img_Thr, img_Thr_T, 125, 255, THRESH_BINARY | THRESH_TRIANGLE);
48.    imshow("img_Thr", img_Thr);
49.    imshow("img_Thr_O", img_Thr_O);
50.    imshow("img_Thr_T", img_Thr_T);
51.  
52.    //灰度图像自适应二值化
53.    Mat adaptive_mean, adaptive_gauss;
54.    adaptiveThreshold(img_Thr, adaptive_mean, 255, ADAPTIVE_THRESH_MEAN_C,
55.                                                                           THRESH_BINARY, 55, 0);
56.    adaptiveThreshold(img_Thr, adaptive_gauss, 255, ADAPTIVE_THRESH_GAUSSIAN_C,
57.                                                                           THRESH_BINARY, 55, 0);
58.  
59.    imshow("adaptive_mean", adaptive_mean);
60.    imshow("adaptive_gauss", adaptive_gauss);
61.    waitKey(0);
62.    return 0;
63.  }

图3-15 threshold()函数处理结果

图3-16 adaptiveThreshold()函数处理结果

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小白学视觉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
“大脑”生长系列(三)
二值化就是将图像上的像素点的灰度值设置为0或255,通过一个阈值来判断,假设像素的值大于100设为255,小于100设为0便是一种策略。
视界音你而不同
2020/04/10
2620
“大脑”生长系列(三)
【OpenCV入门之十八】通过形态学操作提取水平与垂直线
学习计算机视觉最重要的能力应该就是编程了,为了帮助小伙伴尽快入门计算机视觉,小白准备了【OpenCV入门】系列。新的一年文章的内容进行了很大的完善,主要是借鉴了更多大神的文章,希望让小伙伴更加容易理解。如果小伙伴觉得有帮助,请点击一下文末的“好看”鼓励一下小白。
小白学视觉
2019/05/31
8340
图像处理笔记(3)----OpenCV图像算术运算
我想把OpenCV的标志放到另一幅图像上,如果使用相加add函数,颜色会改变,使用addWeighted函数会得到透明效果,怎么做呢?
小火柴棒
2020/09/07
4380
图像处理笔记(3)----OpenCV图像算术运算
OpenCV之图像二值寻找算法 – TRIANGLE
python代码: import cv2 as cv import numpy as np #import tensorflow as tf # tf.enable_eager_execution() # # THRESH_BINARY = 0 # THRESH_BINARY_INV = 1 # THRESH_TRUNC = 2 # THRESH_TOZERO = 3 # THRESH_TOZERO_INV = 4 # src = cv.imread("./test.png") cv.namedWindo
MachineLP
2021/08/13
3630
OpenCV之图像二值寻找算法 – OTSU
python代码: import cv2 as cv import numpy as np # # THRESH_BINARY = 0 # THRESH_BINARY_INV = 1 # THRESH_TRUNC = 2 # THRESH_TOZERO = 3 # THRESH_TOZERO_INV = 4 # src = cv.imread("./test.png") cv.namedWindow("input", cv.WINDOW_AUTOSIZE) cv.imshow("input", src) h
MachineLP
2021/08/13
3320
二值化阈值处理
算法:二值化阈值处理是将原始图像处理为仅有两个值的二值图像。二值化阈值处理是将灰度值大于阈值的像素设为白色(255),小于或等于阈值的像素设为黑色(0);或将大于阈值的像素设为黑色(0),小于或等于阈值的像素设为白色(255),二者只是显示形式不同。二值化阈值应用在边缘提取、图像分割、目标识别等领域。
裴来凡
2022/05/28
1.9K0
二值化阈值处理
OpenCV二值化adaptiveThreshold与threshold的对比
前一篇文章《Android划矩形截屏并加入OCR识别》在安卓中我们做了划矩形截图进行OCR实识,其中只是简单的进行了二值化的处理然后就传入图片识别,本来计划把图片二值化后做一些透视变换的Demo可以增加识别的效果,然后就出来了今天的文章。
Vaccae
2019/10/28
3.7K0
OpenCV二值化adaptiveThreshold与threshold的对比
OpenCV基础 | 11.图像二值化
学习视频可参见python+opencv3.3视频教学 基础入门[1] outline 图像二值化 二值图像 图像二值化方法 OpenCV相关API使用 图像二值化 1.二值图像 二值图像就是将灰度图转化成黑白图,没有灰,在一个值之前为黑,之后为白 2.二值化方法 全局阈值 对整幅图像都是用一个统一的阈值来进行二值化 局部阈值 像素的邻域块的像素值分布来确定该像素位置上的二值化阈值 3.OpenCV中图像二值化方法 二值化函数threshold 函数原型 关于常见的阈值使用方法如下表 OTSU(最大类间方差
快学Python
2021/08/09
7650
opencv 特征值_直方图阈值图像分割
  像素值高于阈值时,给这个像素赋予一个新值(可能是白色),否则我们给它赋予另外一种颜色(也许是黑色)。这个函数就是 cv2.threshhold()。这个函数的第一个参数就是原图像,原图像应该是灰度图。第二个参数就是用来对像素值进行分类的阈值。第三个参数就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值。 OpenCV提供了多种不同的阈值方法,这是有第四个参数来决定的。这些方法包括: • cv2.THRESH_BINARY • cv2.THRESH_BINARY_INV • cv2.THRESH_TRUNC • cv2.THRESH_TOZERO • cv2.THRESH_TOZERO_INV
全栈程序员站长
2022/09/19
6370
opencv 特征值_直方图阈值图像分割
Python-OpenCV(7)
本文介绍了图像阈值处理方法,包括简单阈值、自适应阈值、Otsu阈值、自适应Otsu阈值等方法,并介绍了这些方法在图像处理中的应用。
GavinZhou
2018/01/02
6690
Python-OpenCV(7)
OpenCV之图像二化自适应阈值算法
python代码: import cv2 as cv import numpy as np # # THRESH_BINARY = 0 # THRESH_BINARY_INV = 1 # THRESH_TRUNC = 2 # THRESH_TOZERO = 3 # THRESH_TOZERO_INV = 4 # src = cv.imread("./test.png") cv.namedWindow("input", cv.WINDOW_AUTOSIZE) cv.imshow("input", src)
MachineLP
2021/08/13
9500
CV学习笔记(十二):二值化操作
图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。
云时之间
2020/03/06
1K0
06: 阈值分割
固定阈值分割很直接,一句话说就是像素点值大于阈值变成一类值,小于阈值变成另一类值。
CodecWang
2021/12/07
8550
06: 阈值分割
【CV学习2.0】 OpenCV中的二值化方法
threshold(..,thr,...)和threshold(...,Thr_OTSU,...)
EdenChen
2020/04/27
7480
基于OpenCV的图像分割处理!
图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术。它特别适用于目标和背景占据不同灰度级范围的图像。它不仅可以极大的压缩数据量,而且也大大简化了分析和处理步骤,因此在很多情况下,是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。
Datawhale
2020/07/09
3.6K0
基于OpenCV的图像分割处理!
CV学习笔记(十二):二值化操作
图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。
云时之间
2020/03/19
8980
Python opencv图像处理基础总结(四) 模板匹配 图像二值化
模板匹配是一种最原始、最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题。它是图像处理中最基本、最常用的匹配方法。模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。
叶庭云
2020/09/17
4.9K0
Python  opencv图像处理基础总结(四)  模板匹配  图像二值化
[Python图像处理] 七.图像阈值化处理及民族服饰实验对比
该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类、目标检测应用。
Eastmount
2021/12/02
6320
[Python图像处理] 七.图像阈值化处理及民族服饰实验对比
OpenCV图像处理(十二)---图像阈值化
如果两个热力学系统中的每一个都与第三个热力学系统处于热平衡(温度相同),则它们彼此也必定处于热平衡。这一结论称做“热力学第零定律”。又称热平衡定律,是热力学的四条基本定律之一,是一个关于互相接触的物体在热平衡时的描述,以及为温度提供理论基础。
用户5410712
2022/06/01
5540
OpenCV图像处理(十二)---图像阈值化
简单阈值,自适应阈值,Otsu's二值化等图像阈值处理方法。
import cv2 import numpy as np from matplotlib import pyplot as plt img_path = 'C:/Users/xpp/Desktop/lena.jpg' img = cv2.imread(img_path) img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,th1 = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY) ret,
裴来凡
2022/05/28
7880
简单阈值,自适应阈值,Otsu's二值化等图像阈值处理方法。
相关推荐
“大脑”生长系列(三)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文