OpenCV 自学笔记21. RGB色彩空间和HSV色彩空间的理解

来源:互联网 发布:id 条数MySQL 编辑:程序博客网 时间:2024/04/29 22:41

RGB色彩空间和HSV色彩空间的理解

本文的结构如下:
1、RGB色彩空间
2、HSV色彩空间(附HSV颜色分量范围表)
3、RGB到HSV的转换的Demo
  使用OpenCV实现RGB转HSV,并通过滑动条动态设定HSV阈值
  自己写程序,实现RGB转HSL


1、RGB色彩空间

RGB色彩空间源于使用阴极射线管的彩色电视,RGB分别代表三个基色(R-红色、G-绿色、B-蓝色),具体的色彩值由三个基色叠加而成。在图像处理中,我们往往使用向量表示色彩的值,如(0,0,0)表示黑色、(255, 255, 255)表示白色。其中,255表示色彩空间被量化成255个数,最高亮度值为255(255 = 2^8 - 1,即每个色彩通道用8位表示)。在这个色彩空间中,有256*256*256种颜色。RGB色彩空间如下图所示(图片来自百度百科)。是一个包含Red、Green、Blue的三维空间。

这里写图片描述

注:
1、在OpenCV中,RGB色彩空间的顺序是BGR,千万不要弄错了
2、在Java的Bitmap中,RGB色彩空间被表示为ARGB,其中A代表透明度

2、HSV色彩空间

HSV色彩空间(Hue-色调、Saturation-饱和度、Value-值)将亮度从色彩中分解出来,在图像增强算法中用途很广。在我本人接触的图像处理项目中,经常将图像从RGB色彩空间转换到了HSV色彩空间,以便更好地感知图像颜色,利用HSV分量从图像中提取感兴趣的区域。

HSV色彩空间也被称为HSB(色调、饱和度、亮度),在PS中常被用到。

HSV色彩空间如下图所示,用一个倒圆锥体表示整个色彩空间:

这里写图片描述

注:
1、H的范围是[0,360),S和V的范围是[0,1]。但是在OpenCV 中,HSV好像被规范化到了[0, 255],此处求大神指导。
2、另外,网上有人总结了HSV颜色对应RGB的分量范围,见下面的表格。参考自:
http://www.cnblogs.com/wangyblzu/p/5710715.html
http://blog.csdn.net/taily_duan/article/details/51506776

这里写图片描述

3、RGB到HSV的转换的Demo

(1) 使用OpenCV的cv2.cvtColor(src, cv2.COLOR_BGR2HSV)

OpenCV为我们提供了现成的函数cvtColor(),帮助我们将图像从BGR转换到HSV。

# -*- coding:utf-8 -*-import cv2"""功能:读取一张图片,显示出来,并转化为HSV色彩空间"""image = cv2.imread('images/my_wife2.jpg') # 根据路径读取一张图片cv2.imshow("BGR", image) # 显示图片# 转化图片到HSV色彩空间dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)cv2.imshow("HSV", dst) # 显示图片cv2.waitKey(0) # 等待键盘触发事件,释放窗口

结果如下:

这里写图片描述

挺好看的美女,结果被弄成了这个样子。一些初学者包括我自己有时会问,为什么要把好端端的图片转成HSV色彩空间呢。其实这样做大有用处,比如我们要提取美女的头发区域,就可以通过设置HSV色彩空间的高低阈值来做。

# -*- coding:utf-8 -*-import cv2import numpy as np   # ------------------改变1"""功能:读取一张图片,显示出来,并转化为HSV色彩空间"""image = cv2.imread('images/my_wife2.jpg') # 根据路径读取一张图片cv2.imshow("BGR", image) # 显示图片# 转化图片到HSV色彩空间dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)cv2.imshow("HSV", dst) # 显示图片# 根据HSV提取头发 --------------------------------改变2low_hsv = np.array([0, 0, 46])high_hsv = np.array([200, 40, 220])dst = cv2.inRange(dst, low_hsv, high_hsv)cv2.imshow("result", dst) # 显示图片cv2.waitKey(0) # 等待键盘触发事件,释放窗口

程序的运行效果如下。我们看到,头发区域显示为白色,这样我们就初步地提取出了头发区域。当然这个效果并不理想,是因为我们设定的阈值不好,如果能动态地设定阈值就好了。

这里写图片描述

我们可以利用滑块动态地设置阈值,一边拖动滑块,一边观察图像。OpenCV提供了createTrackbar(),用于创建滑块。代码如下:

# -*- coding:utf-8 -*-import cv2import numpy as np"""功能:读取一张图片,显示出来,转化为HSV色彩空间     并通过滑块调节HSV阈值,实时显示"""image = cv2.imread('images/my_wife2.jpg') # 根据路径读取一张图片cv2.imshow("BGR", image) # 显示图片hsv_low = np.array([0, 0, 0])hsv_high = np.array([0, 0, 0])# 下面几个函数,写得有点冗余def h_low(value):    hsv_low[0] = valuedef h_high(value):    hsv_high[0] = valuedef s_low(value):    hsv_low[1] = valuedef s_high(value):    hsv_high[1] = valuedef v_low(value):    hsv_low[2] = valuedef v_high(value):    hsv_high[2] = valuecv2.namedWindow('image')cv2.createTrackbar('H low', 'image', 0, 255, h_low) cv2.createTrackbar('H high', 'image', 0, 255, h_high)cv2.createTrackbar('S low', 'image', 0, 255, s_low)cv2.createTrackbar('S high', 'image', 0, 255, s_high)cv2.createTrackbar('V low', 'image', 0, 255, v_low)cv2.createTrackbar('V high', 'image', 0, 255, v_high)while True:    dst = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # BGR转HSV    dst = cv2.inRange(dst, hsv_low, hsv_high) # 通过HSV的高低阈值,提取图像部分区域    cv2.imshow('dst', dst)    if cv2.waitKey(1) & 0xFF == ord('q'):        breakcv2.destroyAllWindows()

程序运行的效果如下,我们拉动滑块会自动改变HSV的高低阈值,进而根据高低阈值提取的图像区域也会改变:

这里写图片描述

(2) 自己编写程序实现RGB转HSL

根据维基百科,RGB转HSV的公式如下: 设 (r, g,b)分别是一个颜色的红、绿和蓝坐标,它们的值是在0到1之间的实数。设max等价于r,g和b中的最大者。设min等于这些值中的最小者。要找到在HSL空间中的 (h, s, l)值,这里的h ∈ [0,360)度是角度的色相角,而s, l ∈ [0,1]是饱和度和亮度,计算为:

这里写图片描述

如果要转化为HSV)h的值通常规范化到位于0到360°之间。而h = 0用于max = min的(就是灰色)时候而不是留下h未定义。HSL和HSV有同样的色相定义,但是其他分量不同。HSV颜色的s和v的值定义如下:

这里写图片描述

根据以上公式,我们可以写出RGB转HSV的代码:

def rgb2hsv(r, g, b):    r, g, b = r / 255.0, g / 255.0, b / 255.0    mx = max(r, g, b)    mn = min(r, g, b)    diff = mx - mn    # 计算H    if mx == mn:        h = 0    elif mx == r:        if g >= b:            h = 60 * ((g - b) / diff) + 0        else:            h = 60 * ((g - b) / diff) + 360    elif mx == g:        h = 60 * ((b - r) / diff) + 120    elif mx == b:        h = 60 * ((r - g) / diff) + 240    # 先计算L    l = (mx + mn) / 2.0    # 再计算S    if mx == min:        s = 0    elif l > 0 and l <= 0.5:        s = (diff / l) / 2.0    elif l > 0.5:        s = (diff / (1 - l)) / 2.0    return h, s, l# 测试h,s,l = rgb2hsv(200, 221, 221)print('h=%f s=%f l=%f' % (h, s, l))

程序运行结果如下:
这里写图片描述

可以根据颜色代码表,判断我们的结果是否正确

这里写图片描述

附:

1、 HSV转RGB的公式

类似的,给定在HSV中 (h, s,
v)值定义的一个颜色,带有如上的h,和分别表示饱和度和明度的s和v变化于0到1之间,在RGB空间中对应的 (r, g,
b)三原色可以计算为(R,G,B变化于0到1之间):

这里写图片描述

对于每个颜色向量 (r, g, b),

这里写图片描述

(参考自维基百科)

2、RGB转GRAY的公式

请见:http://blog.csdn.net/xdrt81y/article/details/8289963

总结:
本文包括以下几个部分,
1、RGB和HSV色彩空间的理解
2、通过OpenCV实现了RGB到HSV的转换,包含一个使用滑动条的小例子
3、根据RGB转HSL的公式,自己编程实现了RGB转HSL的程序。

今天就到这里吧,拜拜~~

这里写图片描述

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子不肯上幼儿园怎么办 孩子不肯去幼儿园怎么办 小孩记不住字怎么办 小孩不会写字要怎么办 一年级孩子不爱写字怎么办 一年级小孩不爱写字怎么办 孩子不爱写字怎么办呢 幼儿园孩子不爱写字怎么办 孩子上学没学籍怎么办 孩子上学务工证怎么办 孩子上学被欺负怎么办 孩子害怕上幼儿园怎么办 孩子写字肩膀疼怎么办 5岁不会写字怎么办 上中班不爱写字怎么办 孩子性子太慢怎么办 13小孩特别懒怎么办 小孩不肯上幼儿园怎么办 宝宝不肯上幼儿园怎么办 宝宝不肯去幼儿园怎么办 小孩子不肯去幼儿园怎么办 上幼儿园不说话怎么办 小孩写字不认真怎么办 游戏打开是乱码怎么办 小孩不写字该怎么办 小孩不喜欢穿袜子怎么办 宝宝不喜欢穿袜子怎么办 看到婆婆就烦怎么办 什么也不想吃怎么办 宝宝不喜欢带围兜怎么办 宝宝宝宝不喜欢脐疝带怎么办 中班小孩不写字怎么办 中班小孩不愿意写字怎么办 中班了不会写字怎么办 胃不舒服没胃口怎么办 不喜欢婆婆带孩子怎么办 小孩咳嗽吃饭吐怎么办 小孩吐不吃饭怎么办 小孩吃饭容易吐怎么办 不想婆婆带孩子怎么办 2周宝宝便秘怎么办