【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);

效果如下:

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

    可以看到对于这张图片,在上述的参数情况下,二值化和反二值化方法能更好地分离图像中的墙壁、打火机等对象。
    也可以改变参数或者使用滑动条来挑选更适合每种方法的参数。
相关推荐
漫漫进阶路1 小时前
VS C++ 配置OPENCV环境
开发语言·c++·opencv
bohu831 小时前
亚博microros小车-原生ubuntu支持系列:8-脸部检测与人脸特效
linux·opencv·ubuntu·dlib·microros·亚博
架构文摘JGWZ3 小时前
FastJson很快,有什么用?
后端·学习
量子-Alex5 小时前
【多视图学习】显式视图-标签问题:多视图聚类的多方面互补性研究
学习
Quz5 小时前
OpenCV:高通滤波之索贝尔、沙尔和拉普拉斯
图像处理·人工智能·opencv·计算机视觉·矩阵
去往火星5 小时前
OpenCV文字绘制支持中文显示
人工智能·opencv·计算机视觉
乔木剑衣5 小时前
Java集合学习:HashMap的原理
java·学习·哈希算法·集合
练小杰6 小时前
Linux系统 C/C++编程基础——基于Qt的图形用户界面编程
linux·c语言·c++·经验分享·qt·学习·编辑器
皮肤科大白6 小时前
如何在data.table中处理缺失值
学习·算法·机器学习
皮肤科大白6 小时前
“““【运用 R 语言里的“predict”函数针对 Cox 模型展开新数据的预测以及推理。】“““
学习