opencv-20 深入理解HSV 色彩空间(通过指定,标记颜色等来拓展ROI区域)

RGB 色彩空间是一种被广泛接受的色彩空间,但是该色彩空间过于抽象,我们不能够直接通过其值感知具体的色彩。
我们更习惯使用直观的方式来感知颜色,HSV 色彩空间提供了这样 的方式。
通过 HSV色彩空间,我们能够更加方便地通过色调、饱和度和亮度来感知颜色。 其实,除了 HSV 色彩空间,我们讨论的其他大多数色彩空间都不方便人们对颜色进行理解和解释。例如,现实中我们根本不可能用每种颜料的百分比(RGB
色彩空间)来形容一件衣服的颜色。

HSV 色彩空间从心理学和视觉的角度出发,提出人眼的色彩知觉主要包含三要素:
 H:色调(Hue,也称为色相)。
 S:饱和度(Saturation)。
 V:亮度(Value)。

1.色调H

在 HSV 色彩空间中,色调 H 的取值范围是[0,360]。8 位图像内每个像素点所能表示的灰度级有 28=256 个,所以在 8 位图像内表示 HSV 图像时,要把色调的角度值映射到[0,255]范围内。

在 OpenCV 中,可以直接把色调的角度值除以 2,得到[0,180]之间的值,以适应 8 位二进制(256 个灰度级)的存储和表示范围。

在 HSV 空间中,色调值为 0 表示红色,色调值为 300 表示品红色,具体如表 4-3 所示。

在这里插入图片描述
根据上述分析可知,每个色调值对应一个指定的色彩,而与饱和度和亮度无关。
在 OpenCV中,将色调值除以 2 之后,会得到如表 4-4 所示的色调值与对应的颜色。

在这里插入图片描述
确定值范围后,就可以直接在图像的 H 通道内查找对应的值,从而找到特定的颜色。
例如,在 HSV 图像中,H 通道内值为 120 的像素点对应蓝色。查找 H 通道内值为 120 的像素点,找到的就是蓝色像素点。

在上述基础上,通过分析各种不同对象对应的 HSV 值,便可以查找不同的对象。

例如,通过分析得到肤色的 HSV 值,就可以直接在图像内根据肤色的 HSV 值来查找人脸(等皮肤)区域

2.饱和度S

饱和度值的范围是[0,1],所以针对饱和度,需要说明以下问题:

 灰度颜色所包含的 R、G、B 的成分是相等的,相当于一种极不饱和的颜色。所以,灰度颜色的饱和度值是 0。

 作为灰度图像显示时,较亮区域对应的颜色具有较高的饱和度。

 如果颜色的饱和度很低,那么它计算所得色调就不可靠。

19 节介绍 cv2.cvtColor()函数时,进行色彩空间转换后,为了适应 8 位图的256 个像素级,需要将新色彩空间内的数值映射到[0,255]范围内。所以,同样要将饱和度 S 的值从[0,1]范围映射到[0,255]范围内。

3亮度V
亮度的范围与饱和度的范围一致,都是[0,1]。同样,亮度值在
OpenCV 内也将值映射到[0,255]范围内。

亮度值越大,图像越亮;亮度值越低,图像越暗。当亮度值为 0 时,图像是纯黑色

获取指定颜色

可以通过多种方式获取 RGB 色彩空间的颜色值在 HSV 色彩空间内所对应的值。
例如,可以通过图像编辑软件或者在线网站获取 RGB 值所对应的 HSV 值。

需要注意,在从 RGB/BGR 色彩空间转换到 HSV 色彩空间时,OpenCV 为了满足 8 位图的要求,对 HSV 空间的值进行了映射处理。所以,通过软件或者网站获取的 HSV 值还需要被进一步映射,才能与 OpenCV 中的 HSV 值一致。

OpenCV 中,测试 RGB 色彩空间中不同颜色的值转换到 HSV 色彩空间后的对应值。

为了方便理解,这里分别对蓝色、绿色、红色的单个像素点进行测试。
首先,使用 np.zeros([1,1,3],dtype=np.uint8)来生成一幅仅有一个像素点的图像(数组)。

接下来,通过对其中的通道分量赋值,将其设定为指定的颜色。例如:
 语句 imgBlue[0,0,0]=255 可以将该像素点的第 0 个通道(即 B 通道)的值设置为 255,即将该点的颜色指定为蓝色。

 语句 imgGreen[0,0,1]=255 可以将该像素点的第 1 个通道(即 G 通道)的值设置为 255,
即将该点的颜色指定为绿色。
 语句 imgRed[0,0,2]=255 可以将该像素点的第 2 个通道(即 R 通道)的值设置为 255,
即将该点的颜色指定为红色。

然后,可以通过语句 cv2.cvtColor(Blue,cv2.COLOR_BGR2HSV)将 Blue 从 BGR 色彩空间转换到 HSV 色彩空间。

最后,通过打印 HSV 色彩空间内的像素值,观察转换情况。
在本例中,对蓝色、绿色、红色三种不同的颜色分别进行转换,将它们从 BGR 色彩空间
转换到 HSV 色彩空间,并观察转换后所得到的 HSV 空间的对应值。

根据上面的流程用代码来验证下,代码如下:

import cv2
import numpy as np
#=========测试一下 OpenCV 中蓝色的 HSV 模式值=============
imgBlue=np.zeros([1,1,3],dtype=np.uint8)
#将 BGR 色彩空间中的蓝色的值赋值给 imgBlue
imgBlue[0,0,0]=255
Blue=imgBlue
#将 BGR 色彩空间中的蓝色的值转换为 HSV 色彩空间的值
BlueHSV=cv2.cvtColor(Blue,cv2.COLOR_BGR2HSV)
print("Blue=\n",Blue)
print("BlueHSV=\n",BlueHSV)
#=========测试一下 OpenCV 中绿色的 HSV 模式值=============
imgGreen=np.zeros([1,1,3],dtype=np.uint8)
imgGreen[0,0,1]=255
Green=imgGreen
GreenHSV=cv2.cvtColor(Green,cv2.COLOR_BGR2HSV)
print("Green=\n",Green)
print("GreenHSV=\n",GreenHSV)
#=========测试一下 OpenCV 中红色的 HSV 模式值=============
imgRed=np.zeros([1,1,3],dtype=np.uint8)
imgRed[0,0,2]=255
Red=imgRed
RedHSV=cv2.cvtColor(Red,cv2.COLOR_BGR2HSV)
print("Red=\n",Red)
print("RedHSV=\n",RedHSV)

运行结果

Blue=[[[255   0   0]]]
BlueHSV=[[[120 255 255]]]
Green=[[[  0 255   0]]]
GreenHSV=[[[ 60 255 255]]]
Red=[[[  0   0 255]]]
RedHSV=[[[  0 255 255]]]

标记指定颜色

HSV 色彩空间中,H 通道(饱和度 Hue 通道)对应不同的颜色。或者换个角度理解,颜色的差异主要体现在 H 通道值的不同上。所以,通过对 H 通道值进行筛选,便能够筛选出特定的颜色。

例如,在一幅 HSV 图像中,如果通过控制仅仅将 H 通道内值为 240(在 OpenCV内被调整为 120)的像素显示出来,那么图像中就会仅仅显示蓝色部分。
本节将首先通过例题展示一些实现上的细节问题,然后通过具体例题展示如何将图像内的特定颜色标记出来,即将一幅图像内的其他颜色屏蔽,仅仅将特定颜色显示出来。

通过opencv.inRange()函数锁定特定值

OpenCV 中通过函数 cv2.inRange()来判断图像内像素点的像素值是否在指定的范围内,其语法格式为:

dst = cv2.inRange( src, lowerb, upperb )

式中:
 dst 表示输出结果,大小和 src 一致。
 src 表示要检查的数组或图像。
 lowerb 表示范围下界。
 upperb 表示范围上界。

返回值 dst 与 src 等大小,其值取决于 src 中对应位置上的值是否处于区间[lowerb,upperb]
内:
 如果 src 值处于该指定区间内,则 dst 中对应位置上的值为 255。
 如果 src 值不处于该指定区间内,则 dst 中对应位置上的值为 0。

实验验证:分别提取 OpenCV 的 logo 图像内的红色、绿色、蓝色。

在实际提取颜色时,往往不是提取一个特定的值,而是提取一个颜色区间。
例如,在 OpenCV 中的 HSV 模式内,蓝色在 H 通道内的值是 120。在提取蓝色时,通常将“蓝色值 120”附近的一个区间的值作为提取范围。该区间的半径通常为 10 左右,例如通常提取
[120−10,120+10]范围内的值来指定蓝色。
相比之下,HSV 模式中 S 通道、V 通道的值的取值范围一般是[100,255]。这主要是因为,当饱和度和亮度太低时,计算出来的色调可能就不可靠了。
根据上述分析,各种颜色的 HSV 区间值分布在[H−10,100,100]和[H+10,255,255]之间。因此,各种颜色值的范围为:

 蓝色:值分布在[110,100,100]和[130,255,255]之间。
 绿色:值分布在[50,100,100]和[70,255,255]之间。
 红色:值分布在[0,100,100]和[10,255,255]之间。

根据前述例题的相关介绍,首先利用函数 cv2.inRange()查找指定颜色区域,然后利用基于掩码的按位与运算将指定颜色提取出来。

实验原图:
在这里插入图片描述
代码如下:

import cv2
import numpy as np
opencv=cv2.imread("opencv.jpg")
hsv = cv2.cvtColor(opencv, cv2.COLOR_BGR2HSV)
cv2.imshow('opencv',opencv)
#=============指定蓝色值的范围=============
minBlue = np.array([110,50,50])
maxBlue = np.array([130,255,255])
#确定蓝色区域
mask = cv2.inRange(hsv, minBlue, maxBlue)
#通过掩码控制的按位与运算,锁定蓝色区域
blue = cv2.bitwise_and(opencv,opencv, mask= mask)
cv2.imshow('blue',blue)
#=============指定绿色值的范围=============
minGreen = np.array([50,50,50])
maxGreen = np.array([70,255,255])
#确定绿色区域
mask = cv2.inRange(hsv, minGreen, maxGreen)
#通过掩码控制的按位与运算,锁定绿色区域
green = cv2.bitwise_and(opencv,opencv, mask= mask)
cv2.imshow('green',green)
#=============指定红色值的范围=============
minRed = np.array([0,50,50])
maxRed = np.array([30,255,255])
#确定红色区域
mask = cv2.inRange(hsv, minRed, maxRed)
#通过掩码控制的按位与运算,锁定红色区域
red= cv2.bitwise_and(opencv,opencv, mask= mask)
cv2.imshow('red',red)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果如下,分别提取了不同的颜色出来

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/10667.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python补充笔记5-模块化、文件

目录 一、模块 二、模块的导入 三、python中的包​编辑 四、常用的内容模块 五、第三方模块的安装与使用 六、编码格式的介绍 七、文件读写的原理 八、常用的文件打开模式 ​九、文件对象的常用方法 十、with语句​编辑 十一、os模块的常用函数 十二、os.path模块的常用方法​编…

今天学学消息队列RocketMQ:消息类型

RocketMQ支持的消息类型有三种:普通消息、顺序消息、延时消息、事务消息。以下内容的代码部分都是基于rocketmq-spring-boot-starter做的。 普通消息 普通消息是一种无序消息,消息分布在各个MessageQueue当中,以保证效率为第一使命。这种消息…

Staples Drop Ship EDI 需求分析

Staples 是一家美国零售公司,总部位于马萨诸塞州弗拉明汉,主要提供支持工作和学习的产品和服务。该公司于 1986 年在马萨诸塞州布莱顿开设了第一家门店。到 1996 年,该公司已跻身《财富》世界 500 强,后来又收购了办公用品公司 Qu…

MySQL优化(面试)

文章目录 通信优化查询缓存语法解析及查询优化器查询优化器的策略 性能优化建议数据类型优化索引优化 优化关联查询优化limit分页对于varchar end mysql查询过程: 客户端向MySQL服务器发送一条查询请求服务器首先检查查询缓存,如果命中缓存,则立刻返回存…

初识mysql数据库之事务的概念及操作

目录 一、数据库多客户端访问问题 1. 数据库的CURD无限制带来的问题 2. 如何解决CURD导致的问题 二、事务的概念 1. 什么是事务 2. 事务的四个属性 3. mysql对事务的管理 4. 为什么会有事务 5. 事务的版本支持 三、事务的操作 1. 事务提交方式 2. 事务操作的准备工…

哈工大计算机网络课程局域网详解之:无线局域网

哈工大计算机网络课程局域网详解之:无线局域网 文章目录 哈工大计算机网络课程局域网详解之:无线局域网IEEE 802.11无线局域网802.11体系结构802.11:信道与AP关联 本节介绍一下平时经常使用的一个无线局域网技术,也就是通常我们使…

3ds MAX绘制茶壶

综合一下之前的内容画个茶壶 长方形,然后转化为可编辑多边形,添加节点并设置圆角,如下图 车削生成一个圆环,其实这一步也可以用一个圆柱体和两个圆角圆柱体解决 效果如下: 茶壶的底座绘制好了 接下来是茶壶的上半边 …

TypeScript -- 函数

文章目录 TypeScript -- 函数JS -- 函数的两种表现形式函数声明函数的表达式es6 箭头函数 TS -- 定义一个函数TS -- 函数声明使用接口(定义)ts 定义参数可选参数写法 -- ?的使用TS函数 -- 设置剩余参数函数重载 TypeScript – 函数 JS – 函数的两种表现形式 我们熟知js有两…

history命令:显示命令执行时间

1.修改配置文件 vim /etc/profile 添加内容 export HISTTIMEFORMAT"%Y-%m-%d %H:%M:%S " ​ #注意:在末尾的“引号”与“S”之间,加入一位空格,将日期时间和历史命令用空格相隔开来。 你也可以换一种清晰的形式,效果…

实验三 贪心算法

实验三 贪心算法 迪杰斯特拉的贪心算法实现 优先队列等 1.实验目的 1、掌握贪心算法的基本要素 :最优子结构性质和贪心选择性质 2、应用优先队列求单源顶点的最短路径Dijkstra算法,掌握贪心算法。 2.实验环境 Java 3.问题描述 给定带权有向图G (V…

背包问题求具体方案数问题--板子题

12. 背包问题求具体方案 - AcWing题库 思路:先将v[i]和w[i]先输入进去,然后我们进行倒叙dp,这个做的目的就是为了后边我们为了匹配确定路径做好准备,如果我们倒叙输入进去,我们再正序的时候就可以用推导式来进行路径输…

DevOps(四)

CD(二) 1. CDStep 1 - 上传代码Step 2 - 下载代码Step 3 - 检查代码Step 4 - 编译代码Step 5 - 上传仓库Step 6 - 下载软件Step 7 - 制作镜像Step 8 - 上传镜像Step 9 - 部署服务2. 整体预览2.1 预览1. 修改代码2. 查看sonarqube检查结果3. 查看nexus仓库4. 查看harbor仓库5.…

Hadoop简介以及集群搭建详细过程

Hadoop简介以及集群搭建详细过程 hadoop集群简介hadoop部署模式Hadoop集群安装1.集群角色规划2.服务器基础环境准备3.上传安装包hadoop安装包目录结构5.编辑hadoop配置文件6.分发安装包7.配置hadoop环境变量8.NameNode format(格式化操作) hadoop集群启动关闭-手动逐个进程启停…

【低代码专题方案】使用iPaaS平台下发数据,快捷集成MDM类型系统

01 场景背景 伴随着企业信息化建设日趋完善化、体系化,使用的应用系统越来越多,业务发展中沉淀了大量数据。主数据作为数据治理中枢,保存大量标准数据库,如何把庞大的数据下发到各个业务系统成了很棘手的问题。 传统的数据下发方…

android app控制ros机器人一

android开发app,进而通过控制ros机器人,记录开发过程 查阅资料: rosjava使用较多,已经开发好的app也有开源的案例 rosjava GitHub https://github.com/ros-autom/RobotCA https://github.com/ROS-Mobile/ROS-Mobile-Android…

Pandas时序数据分析实践—概述

时序数据,作为一种时间上有序的数据形式,无疑是我们日常生活中最常见的数据类型之一。它记录了事件、现象或者过程随时间的变化,是对于许多实际场景的忠实反映。而在众多时序数据的应用领域中,跑步训练记录莫过于是一项令人着迷的…

亲测解决Git inflate: data stream error (incorrect data check)

Git inflate: data stream error (incorrect data check) error: unable to unpack… 前提是你的repository在github等服务器或者其他路径有过历史备份/副本,不要求是最新版本的,只要有就可能恢复你做的所有工作。 执行git fsck --full检查损坏的文件 在…

《TCP IP网络编程》第十一章

第 11 章 进程间通信 11.1 进程间通信的基本概念 通过管道实现进程间通信: 进程间通信,意味着两个不同的进程中可以交换数据。下图是基于管道(PIPE)的进程间通信的模型: 可以看出,为了完成进程间通信&…

数据决定AIGC的高度,什么又决定着数据的深度?

有人曾言,数据决定人工智能发展的天花板。深以为然。 随着ChatGPT等AIGC应用所展现出的强大能力,人们意识到通用人工智能的奇点正在来临,越来越多的企业开始涌入这条赛道。在AIGC浪潮席卷全球之际,数据的重要性也愈发被业界所认同…

MySQL基础(四)数据库备份

目录 前言 一、概述 1.数据备份的重要性 2.造成数据丢失的原因 二、备份类型 (一)、物理与逻辑角度 1.物理备份 2.逻辑备份 (二)、数据库备份策略角度 1.完整备份 2.增量备份 三、常见的备份方法 四、备份&#xff08…