【OpenCV C++20 学习笔记】阈值操作—分离图片对象

阈值操作---分离图片对象

原理

用阈值来分离图片中的对象是一种最简单的分离方法。根据我们想要分离的图片中的对象,设置特定的阈值,然后通过将图片的每个像素值与该阈值进行对比,从而确定我们想要的图像中的区域。

二值化类型

OpenCV中的threshold函数共有5种类型的阈值操作方法可选。

首先我们有一张原图,图中像素点的值用 s r c ( x , y ) src(x,y) src(x,y)表示,该图片中的颜色分布图如下(纵轴为颜色值,横轴为不同像素点,蓝线为固定阈值):

二值化(Threshold Binary)

二值化操作的具体方法用公式表示为:
d s t ( x , y ) = { m a x V a l u e if s r c ( x , y ) > t h r e s h o l d 0 otherwise dst(x,y)= \begin{cases} maxValue & \text{if} \quad src(x,y) > threshold \\ 0 & \text{otherwise} \end{cases} dst(x,y)={maxValue0ifsrc(x,y)>thresholdotherwise

  • d s t ( x , y ) 为像素点阈值操作后的结果,下同 dst(x,y)为像素点阈值操作后的结果,下同 dst(x,y)为像素点阈值操作后的结果,下同

即,如果像素点的颜色值 s r c ( x , y ) src(x,y) src(x,y)高于阈值 t h r e s h o l d threshold threshold,该像素点就会被赋予用户定义的 m a x V a l u e maxValue maxValue;否则的话,像素点就会被赋予0值。

其效果用颜色值分布图表示,如下:

反二值化(Threshold Binary, Inverted)

反二值化与二值化正好相反,用公式表达为:
d s t ( x , y ) = { 0 if s r c ( x , y ) > t h r e s h o l d m a x V a l u e otherwise dst(x,y)= \begin{cases} 0 & \text{if} \quad src(x,y)>threshold \\ maxValue & \text{otherwise} \end{cases} dst(x,y)={0maxValueifsrc(x,y)>thresholdotherwise

即,超过阈值的像素点都被赋予0值,而没有超过的都被赋予 m a x V a l u e maxValue maxValue。

用颜色值分布图表示如下:

截断(Truncate)

截断的具体方法用公式表示如下:
d s t ( x , y ) = { t h r e s h o l d if s r c ( x , y ) > t h r e s h o l d s r c ( x , y ) otherwise dst(x,y)= \begin{cases} threshold & \text{if} \quad src(x,y)>threshold \\ src(x,y) & \text{otherwise} \end{cases} dst(x,y)={thresholdsrc(x,y)ifsrc(x,y)>thresholdotherwise

即,超过阈值的像素点被赋予阈值的值,而没有超过的则保留原值。

用颜色分布图表示如下:

零值化

零值化操作用公式表达如下:
d s t ( x , y ) = { s r c ( x , y ) if s r c ( x , y ) > t h r e s h o l d 0 otherwise dst(x,y)= \begin{cases} src(x,y) & \text{if} \quad src(x,y)>threshold \\ 0 & \text{otherwise} \end{cases} dst(x,y)={src(x,y)0ifsrc(x,y)>thresholdotherwise

即,如果超过阈值就保留原值,没有超过阈值就赋予0值。

用颜色值分布图表示如下:

反零值化

顾名思义这个方法是零值化方法的反面,用公式表示如下:
d s t ( x , y ) = { 0 if s r c ( x , y ) > t h r e s h o l d s r c ( x , y ) otherwise dst(x,y)= \begin{cases} 0 & \text{if} \quad src(x,y)>threshold \\ src(x,y) & \text{otherwise} \end{cases} dst(x,y)={0src(x,y)ifsrc(x,y)>thresholdotherwise

即,超过阈值的像素点赋予0值,没有超过阈值的保留原值。

用颜色分布图表示其结果如下:

代码实现

本示例使用的图片可以在下载OpenCV文件夹中找到:"...\opencv\sources\samples\data\stuff.jpg"。原图如下:

5种类型的阈值操作都是用cv:threshold函数实现的,该函数原型如下:

cpp 复制代码
double cv::threshold(InputArray	src,
					OutputArray	dst,
					double		threshold,
					double		maxValue,
					int			type)
  • src:原图
  • dst:输出图
  • threshold:阈值
  • maxValue:二值化和反二值化中的maxvalue,但是其他方法中也需要指定,不过用不到
  • type:阈值操作类型
    * THRESH_BINARY:二值化,0
    * THRESH_BINARY_INV:反二值化,1
    * THRESH_TRUNC:截断,2
    * THRESH_TOZERO:零值化,3
    * THRESH_TOZERO_INV:反零值化,4
  • 目前用不到返回值,先不用管

这里将所有的阈值threshold都设置为100;

将二值化和反二值化中的maxValue都设置为255;

cpp 复制代码
//二值化
Mat binary_dst;
threshold(src,
	binary_dst,
	100,
	255,
	0);

//反二值化
Mat inv_binary_dst;
threshold(src,
	inv_binary_dst,
	100,
	255,
	1);

//截断
Mat trunc_dst;
threshold(src,
	trunc_dst,
	100,
	255,
	2);

Mat trunc_dst1;
threshold(src,
	trunc_dst1,
	100,
	150,
	2);

//零值化
Mat zero_dst;
threshold(src,
	zero_dst,
	100,
	255,
	3);

//反零值化
Mat inv_zero_dst;
threshold(src,
	inv_zero_dst,
	100,
	255,
	4);

效果如下:

  • 二值化
  • 反二值化
  • 截断
  • 零值化
  • 反零值化

    可以看到对于这张图片,在上述的参数情况下,二值化和反二值化方法能更好地分离图像中的墙壁、打火机等对象。
    也可以改变参数或者使用滑动条来挑选更适合每种方法的参数。
相关推荐
xuhaoyu_cpp_java2 小时前
项目学习(三)分页查询
java·经验分享·笔记·学习
小宋加油啊4 小时前
机械臂抓取物体 PVN3D算法调研学习
学习·算法·3d
Xzh04235 小时前
AI Agent 学习路线(Java 后端方向)
java·人工智能·学习
做cv的小昊6 小时前
计算机图形学:【Games101】学习笔记08——光线追踪(辐射度量学、渲染方程与全局光照、蒙特卡洛积分与路径追踪)
图像处理·笔记·学习·计算机视觉·游戏引擎·图形渲染·概率论
星恒随风6 小时前
C++ 类和对象入门(五):初始化列表、explicit 和 static 成员详解
开发语言·c++·笔记·学习·状态模式
gis分享者7 小时前
OpenCV 新手入门与实战部署指南
人工智能·opencv·计算机视觉
sensen_kiss7 小时前
CPT304 SoftwareEngineeringII 软件工程 2 Pt.8 软件测试 (Software Testing)(上)
学习·软件工程
力学与人工智能7 小时前
PPT分享 | 洛桑联邦理工学院魏震:深度几何学习在工业设计优化中的应用
学习·优化·工业设计·深度几何学习·洛桑联邦理工学院
sensen_kiss9 小时前
CPT304 SoftwareEngineeringII 软件工程 2 Pt.9 软件测试 (Software Testing)(下)
学习·软件工程
wu_ye_m9 小时前
学习c语言第35天 函数声明和定义
c语言·开发语言·学习