OpenCV颜色空间转换

前言

又是学习OpenCV的一天,我真的越来越喜欢它了,哈哈,不好意思哈!言归正传,这一章节主要讲的是颜色空间的转换。
学习目标是:

  1. 图像从一个颜色空间转换为另一个颜色空间,比如:RGB<=>GRAY,RGB<=>HSV等,这两种是比较常用的。
  2. 常用的两个函数为:cv.cvtcolor()、cv.inrange()通过这一章节可以学习到。
  3. 用视频捕捉摄像头中某种颜色,做出掩模,只显示该颜色的物体。这一功能对后面视频捕捉和机器人跟踪作用很大。
    还是指出官方教程链接

一些思考

按照官方教程实现了视频捕捉,但是发现掩模不是只显示蓝色的物体,一度以为程序上出现问题,用不同颜色物体测试后发现,原来是掩模的阈值设置的有问题,教程上的阈值是捕捉红色的阈值。找到问题后,希望做一个可以灵活选择捕捉颜色的功能,就想到前面学习的拖拽条功能。一方面可以直观的学习和感受一下HSV的颜色空间,另一方面,可以总结出常用的颜色的阈值范围,列出表格,后续使用起来就方便很多。因此,我把官方教程的例子扩展了一下。

实现思路

  1. 读取图片,是否需要resize一下图片大小,方便显示;
  2. 建立拖拽条,和拖拽条位置反馈函数;
  3. 转换颜色空间从RGB<=>HSV;
  4. 做掩模,即设置感兴趣的颜色阈值;
  5. 将原图和掩模,按位求与,用cv.bitwise_and函数。

实现步骤

  1. 读入一张图片
#读入一张图片
o = cv.imread('color24.jpg')
img = cv.resize(o,(380,380),interpolation=cv.INTER_CUBIC)
cv.namedWindow('img')
  1. 创建拖拽条,拖拽条位置函数
def nothing(x):
    pass
#if not cap.isOpened():
    #print('camera cannot open')
    #exit()

lower_h = cv.createTrackbar('lower_h','img',0,255,nothing)
upper_h = cv.createTrackbar('upper_h','img',0,255,nothing)
lower_s = cv.createTrackbar('lower_s','img',0,255,nothing)
upper_s = cv.createTrackbar('upper_s','img',0,255,nothing)
lower_v = cv.createTrackbar('lower_v','img',0,255,nothing)
upper_v = cv.createTrackbar('upper_v','img',0,255,nothing)

def get_hsv():
    h_lower = cv.getTrackbarPos('lower_h','img')
    h_upper = cv.getTrackbarPos('upper_h','img')
    s_lower = cv.getTrackbarPos('lower_s', 'img')
    s_upper = cv.getTrackbarPos('upper_s', 'img')
    v_lower = cv.getTrackbarPos('lower_v', 'img')
    v_upper = cv.getTrackbarPos('upper_v', 'img')
    lower_hsv = np.array([h_lower,s_lower,v_lower])
    upper_hsv = np.array([h_upper,s_upper,v_upper])
    return lower_hsv,upper_hsv
  1. 主函数
while(1):
    #一帧帧的捕捉视频
    lower_hsv, upper_hsv=get_hsv()   
    #转成HSV    
    hsv = cv.cvtColor(img, cv.COLOR_RGB2HSV)
    #定义拾取到蓝色在HSV中的范围:lower_blue\upper_blue
    #做掩模,在图像中只得到蓝色的部分
    mask =cv.inRange(hsv,lower_hsv,upper_hsv)
    #再把掩模和原图像AND在一起,与运算
    res = cv.bitwise_and(img, img, mask=mask)
    cv.imshow('original',img)
    cv.imshow('mask',mask)
    cv.imshow('res',res)
    k = cv.waitKey(5) & 0xFF
    if k ==27:
        break
cv.destroyAllWindows()
  1. 运行结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

RBG和HSV颜色对照小结

这里稍微说一下RGB颜色空间和HSV颜色空间的定义和区别。

  1. RGB颜色空间
    RGB色彩空间源于使用阴极射线管的彩色电视,RGB分别代表三个基色(R-红色、G-绿色、B-蓝色),具体的色彩值由三个基色叠加而成。在图像处理中,我们往往使用向量表示色彩的值,如(0,0,0)表示黑色、(255, 255, 255)表示白色。其中,255表示色彩空间被量化成255个数,最高亮度值为255(255 = 2^8 - 1,即每个色彩通道用8位表示)。在这个色彩空间中,有256256256种颜色。RGB色彩空间如下图所示(图片来自百度百科)。是一个包含Red、Green、Blue的三维空间。
    在这里插入图片描述
  2. HSV色彩空间
    HSV色彩空间(Hue-色调、Saturation-饱和度、Value-值)将亮度从色彩中分解出来,在图像增强算法中用途很广。在我本人接触的图像处理项目中,经常将图像从RGB色彩空间转换到了HSV色彩空间,以便更好地感知图像颜色,利用HSV分量从图像中提取感兴趣的区域。
    HSV形状类似一个锥形。

在这里插入图片描述
通过测试和比对,列出下面表格:

C青 G绿 Y黄 R红 M品红
lower_h -16(164) 21 42 86 112 133
upper_h 21 42 86 112 133 164
lower_s 0 0 0 0 0 0
upper_s 255 255 255 255 255 255
lower_v 0 0 0 0 0 0
upper_v 255 255 255 255 255 255

也不是特别精准,可以起到一定的借鉴作用,具体提取颜色的[h,s,v],作为超参数需要调试和标定,大家要有一定耐心哈!
我们可以找个具有图形的图片先测试一下。
1.首先登场的是,黄色为代表的,非著名动画人物比卡丘
在这里插入图片描述

民那桑,效果不错吧,哈哈!记下HSV的阈值,后面可以继续在视频中跟踪到可爱的化身比卡丘君。

视频捕捉测试

还是回归官网教程,用视频做颜色捕捉,因为所在环境光照比较强,而且是笔记本摄像头,所以电流波动和干扰比较大,其实可以通过滤波实现画面的优化,但这里重点不是说这些操作,后面学到了,我会再写出来。
视频是以一个色卡随机展示一些颜色,从画面中找出蓝色的部分,结果基本可以接受。蓝色的区域用红色线标出来了。
在这里插入图片描述
这一章节内容基本到这了,我会继续学习,不定期更新,先给自己打打气,哈哈,继续学习去了!

版权声明:本文为live4046原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/live4046/article/details/102545168