一:相关api

1:imread

imread(filename, cv.IMREAD_GRAYSCALE)

具体cv.imread及其使用方法和读取有中文路径的图片参考博客OpenCV学习一:图片读取&保存

2:cvtColor

cvtColor(    src,           #输入code[,         #色彩空间转换的代码或表示.dst=None[,     #输出dstCn=None]]#目标图像通道数
);

3getTrackbarPos

getTrackbarPos(滑动条名字,窗口名,输出当前值)

该函数将输入图像从一种颜色空间转换为另一种颜色空间。在从 RGB 颜色空间转换的情况下,应明确指定通道的顺序(RGB 或 BGR)。请注意,OpenCV 中的默认颜色格式通常称为 RGB,但实际上是 BGR(字节反转)。因此,标准(24 位)彩色图像中的第一个字节将是 8 位蓝色分量,第二个字节将是绿色,第三个字节将是红色。然后第四、第五和第六个字节将是第二个像素(蓝色,然后是绿色,然后是红色),依此类推。
R、G 和 B 通道值的常规范围是:
CV_8U 图像为 0 到 255
0 到 65535 用于 CV_16U 图像
CV_32F 图像的 0 到 1

在线性变换的情况下,范围无关紧要。但是在非线性变换的情况下,输入 RGB 图像应该被归一化到适当的值范围以获得正确的结果。例如,如果您有一个 32 位浮点图像直接从 8 位图像转换而来,没有任何缩放,那么它将具有 0——255 的值范围,而不是函数假定的 0——1。因此,在调用cvtColor之前,需要先缩小图像:

img *= 1./255;
cvtColor(img,img,COLOR_BGR2Luv);
如果对 8 位图像使用cvtColor
转换会丢失一些信息。对于许多应用程序,这并不明显,但建议在需要全范围颜色或在操作前转换图像然后再转换回来的应用程序中使用 32 位图像。
如果转换添加 alpha 通道,其值将设置为相应通道范围的最大值:CV_8U 为 255,CV_16U 为 65535,CV_32F 为 1。

二:代码演示

import cv2
import numpy as npdef callback(userdata):passcv2.namedWindow('color', cv2.WINDOW_NORMAL)
img = cv2.imdecode(np.fromfile(r"C:\Users\DMr\Pictures\个人\xiaoqi.jpg",dtype=np.uint8),1)colorspaces = [cv2.COLOR_BGR2RGBA, cv2.COLOR_BGR2BGRA,cv2.COLOR_BGR2GRAY, cv2.COLOR_BGR2HSV,cv2.COLOR_BGR2YUV]
cv2.createTrackbar('curcolor', 'color', 0, 4, callback)while True:index = cv2.getTrackbarPos('curcolor', 'color')#颜色空间转换APIcvt_img = cv2.cvtColor(img, colorspaces[index])cv2.imshow('color', cvt_img)key = cv2.waitKey(10)if key & 0xFF == ord('q'):breakcv2.destroyAllWindows()

输出

三:常见色彩类型

RGB:人眼的色彩空间
BGR:OpenCV,Windows
HSV/HSB-是什么颜色、颜色有多深、颜色有多亮
YUV色彩空间-视频


1:RGB 的局限性

RGB 是我们接触最多的颜色空间,由三个通道表示一幅图像,分别为红色®,绿色(G)和蓝色(B)。这三种颜色的不同组合可以形成几乎所有的其他颜色。

RGB 颜色空间是图像处理中最基本、最常用、面向硬件的颜色空间,比较容易理解。

RGB 颜色空间利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关,而且这三个分量是高度相关的,所以连续变换颜色时并不直观,想对图像的颜色进行调整需要更改这三个分量才行。

自然环境下获取的图像容易受自然光照、遮挡和阴影等情况的影响,即对亮度比较敏感。而 RGB 颜色空间的三个分量都与亮度密切相关,即只要亮度改变,三个分量都会随之相应地改变,而没有一种更直观的方式来表达。

但是人眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。

所以,RGB 颜色空间适合于显示系统,却并不适合于图像处理。

2:HSV 颜色空间

基于上述理由,在图像处理中使用较多的是 HSV 颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比。

在 HSV 颜色空间下,比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。

HSV 表达彩色图像的方式由三个部分组成:

  • Hue(色调、色相)0-360就是我们平时所说的红、绿,如果你分的更细的话可能还会有洋红、草绿等等;在HSV模型中,用度数来描述色相,其中红色对应0度,绿色对应120度,蓝色对应240度。

  • Saturation(饱和度、色彩纯净度)0-255色彩的深浅度(0-100%) ,对于一种颜色比如红色,我们可以用浅红——大红——深红——红得发紫等等语言来描述它(请原谅一个纯理科生的匮乏的颜色系统),对应在画水彩的时候即一种颜料加上不同分量的水形成不同的饱和度。

  • Value(明度)0-255这个在调整屏幕亮度的时候比较常见。

用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。

Hue 用角度度量,取值范围为0~360°,表示色彩信息,即所处的光谱颜色的位置。表示如下:

颜色圆环上所有的颜色都是光谱上的颜色,从红色开始按逆时针方向旋转,Hue=0 表示红色,Hue=120 表示绿色,Hue=240 表示蓝色等等。

在 RGB中 颜色由三个值共同决定,比如黄色为即 (255,255,0);在HSV中,黄色只由一个值决定,Hue=60即可。

HSV 圆柱体的半边横截面(Hue=60):

其中水平方向表示饱和度,饱和度表示颜色接近光谱色的程度。饱和度越高,说明颜色越深,越接近光谱色;饱和度越低,说明颜色越浅,越接近白色。饱和度为0表示纯白色。取值范围为0~100%,值越大,颜色越饱和。

竖直方向表示明度,决定颜色空间中颜色的明暗程度,明度越高,表示颜色越明亮,范围是 0-100%。明度为0表示纯黑色(此时颜色最暗)。
当S=1 V=1时,H所代表的任何颜色被称为纯色;
当S=0时,即饱和度为0,颜色最浅,最浅被描述为灰色(灰色也有亮度,黑色和白色也属于灰色),灰色的亮度由V决定,此时H无意义;
当V=0时,颜色最暗,最暗被描述为黑色,因此此时H(无论什么颜色最暗都为黑色)和S(无论什么深浅的颜色最暗都为黑色)均无意义。

可以通俗理解为:

在Hue一定的情况下,饱和度减小,就是往光谱色中添加白色,光谱色所占的比例也在减小,饱和度减为0,表示光谱色所占的比例为零,导致整个颜色呈现白色。

明度减小,就是往光谱色中添加黑色,光谱色所占的比例也在减小,明度减为0,表示光谱色所占的比例为零,导致整个颜色呈现黑色。

HSV 对用户来说是一种比较直观的颜色模型。我们可以很轻松地得到单一颜色,即指定颜色角H,并让V=S=1,然后通过向其中加入黑色和白色来得到我们需要的颜色。增加黑色可以减小V而S不变,同样增加白色可以减小S而V不变。例如,要得到深蓝色,V=0.4 S=1 H=240度。要得到浅蓝色,V=1 S=0.4 H=240度。

HSV 的拉伸对比度增强就是对 S 和 V 两个分量进行归一化(min-max normalize)即可,H 保持不变。

RGB颜色空间更加面向于工业,而HSV更加面向于用户,大多数做图像识别这一块的都会运用HSV颜色空间,因为HSV颜色空间表达起来更加直观!

RGB➡HSV

  1. V = max(R, G, B)/255.0f——亮度V就是RGB值中最大的那个值进行归一化。
    推论:纯色的RGB中肯定有一个是255。同时RGB值也不可能有3个255,因为3个255为白色,白色为对于任何色彩H,V=1而S=0时的产物。而V=1 S=0并不是纯色。同时如果V=0,那么RGB三者中的最大值是0,即GRB都为0,也就是说该像素是黑色。
  2. S = (max(R, G, B) - min(R, G, B))/(float)max(R, G, B)——饱和度S是RGB中最大值和最小值的差值与最大值的比值。
    推论:
    纯色(S=1 V=1)的RGB值中必定有一个0,因为当S=1,max(R, G, B) - min(R, G, B) == m ax(R, G, B),即RGBMin =0。这也说明了白色(RGB(255,255,255)并不是纯色)。
    当S = 0时,RGBMax-RGBMin == 0,即RGB,此时颜色呈不同程度的灰色(由白到黑,亮度由V而定,因为V=RGBMax*100/255,V越高,RGBMaxRG==B就越高,灰色越亮))。这也可以从上面给出的矩形图看出。
    因此对于纯色来说,RGB中必有一个255和一个0。
    公式换算:

HSV➡RGB

3:HSL


HSL 和 HSV 比较类似,这里一起介绍。HLS 也有三个分量,hue(色相)、saturation(饱和度)、lightness(亮度)。

HSL 和 HSV 的区别就是最后一个分量不同,HLS 的是 light(亮度),HSV 的是 value(明度)。可以到这个 网页 尝试一下。

HSL 中的 L 分量为亮度,亮度为100,表示白色,亮度为0,表示黑色;HSV 中的 V 分量为明度,明度为100,表示光谱色,明度为0,表示黑色。

下面是 HSL 颜色空间圆柱体:

提取白色物体时,使用 HLS 更方便,因为 HSV 中的Hue里没有白色,白色需要由S和V共同决定(S=0, V=100)。而在 HLS 中,白色仅由亮度L一个分量决定。所以检测白色时使用 HSL 颜色空间更准确。

将上面这个 HSL 颜色空间图用来测试:

img = cv2.imread("hls.jpg")# Convert BGR to HLS
imgHLS = cv2.cvtColor(img, cv2.COLOR_BGR2HLS)# range of white color in L channel
# mask = cv2.inRange(imgHLS[:,:,1], lowerb=250, upperb=255)
mask = cv2.inRange(imgHLS, np.array([0,250,0]), np.array([255,255,255]))# Apply Mask to original image
white_mask = cv2.bitwise_and(img, img, mask=mask)

输出

注意:在 OpenCV 中 HLS 三个分量的范围为:
H = [0,179]
L = [0,255]
S = [0,255]

注意:在 OpenCV 中 HSV 三个分量的范围为:
H = [0,180]
S = [0,255]
V = [0,255]

获取要跟踪物体颜色的HSV值:

对一个BGR值进行颜色空间转换,得到HSV值。

 blue = np.uint8([[[255,0,0]]])hsv_blue = cv2.cvtColor(blue, cv2.COLOR_BGR2HSV)print(hsv_blue)  #[[[120 255 255]]]

为了识别特定颜色的物体,获取到颜色所对应的HSV值很重要,这里说一下获取步骤:

1、在线取色器 或 传图识色,可以在这里上传特定颜色的图片,获取这些颜色对应的RGB值。

2、假设获取到的是这样的数据:#869C90,#899F92,#8A9E92,#8A9F8E,下面将其进行转换得到HSV各通道的数值范围:

rgb = '#869C90,#899F92,#8A9E92,#8A9F8E'rgb = rgb.split(',')# 转换为BGR格式,并将16进制转换为10进制
bgr = [[int(r[5:7], 16), int(r[3:5], 16), int(r[1:3], 16)] for r in rgb]# 转换为HSV格式
hsv = [list(cv2.cvtColor(np.uint8([[b]]), cv2.COLOR_BGR2HSV)[0][0]) for b in bgr]hsv = np.array(hsv)
print('H:', min(hsv[:, 0]), max(hsv[:, 0]))
print('S:', min(hsv[:, 1]), max(hsv[:, 1]))
print('V:', min(hsv[:, 2]), max(hsv[:, 2]))

然后对其中的Hue值进行加10和减10(这里的10也可以为其他值,视具体情况而定),得到Hue的范围,还要指定S和V的范围:
最后整个HSV值的上限和下限为 [hue+10,100,100]和 [hue-10,255,255],S和V的下限值可以根据实际情况设置。

因为H=0和H=180都对应红色,所以对于红色的话,需要定义两个范围,并进行取或操作。

sensitivity = 10
lower_red_0 = np.array([0,100,100])
upper_red_0 = np.array([sensitivity,255,255])
lower_red_1 = np.array([180-sensitivity,100,100])
upper_red_1 = np.array([180,255,255])mask_0 = cv2.inRange(hsv, lower_red_0, upper_red_0)
mask_1 = cv2.inRange(hsv, lower_red_1, upper_red_1)mask = cv2.bitwise_or(mask_0, mask_1)

使用 cv2:inRange() 作为基于颜色的阈值。

然后就可以使用该 HSV 值范围进行目标物体的提取。

import cv2
import numpy as np
#cam = cv2.VideoCapture(0)
img = cv2.imread('C:\\Users\\DMr\\Pictures\\text\\phone.jpg', cv2.IMREAD_COLOR)
cv2.imshow("yuantu",img)
Obj_low = np.array([0,0,0])#找到对应对象的HSV颜色
Obj_high = np.array([179,157,79])
while True:#img = cam.read()[1]img = cv2.resize(img, (800,600) )blur_img = cv2.GaussianBlur(img,(23,23),0)#使用高斯滤波器对图像进行归一化cv2.imshow("ga", blur_img)HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)#将图像转换为HSV颜色模型cv2.imshow("hsv", HSV)MASK1 = cv2.inRange(HSV, Obj_low, Obj_high)#在给定的HSV值范围内应用二进制阈值,黑白Obj_low和Obj_high。#MASK2 = cv2.inRange(HSV,Obj2_low,Obj2_high) #如果尝试跟踪两个不同的对象,则需要创建2个不同的蒙版,并最终在两个蒙版上使用“按位与”运算符。#mask = cv2.bitwise_and(mask1,mask2)MASK1 = cv2.erode(MASK1, None, iterations=2)#侵蚀和膨胀:侵蚀和膨胀填充阈值图像中的黑色和白色斑点。这样可使图像更清晰,平滑并突出主要对象MASK1 = cv2.dilate(MASK1, None, iterations =2)cv2.imshow("fushi",MASK1)cnts = cv2.findContours(MASK1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]center = None#轮廓:突出显示对象的图像片段。例如,如果将二进制阈值应用于具有(180,255)的图像,则大于180# 的像素将以白色突出显示,而其他则为黑色。白色部分称为轮廓。if len(cnts)>0 :c = max(cnts, key = cv2.contourArea)#在上面给定的图像中,整个白色边界区域是轮廓。轮廓可能不止一个,但主要对象的面积将最大。所以选择轮廓最大((x,y), radius) = cv2.minEnclosingCircle(c)#得到主要物体的轮廓后,在轮廓上画一个圆M = cv2.moments(c)center = (int(M['m10']/ M['m00']), int(M['m01']/ M['m00']) )if radius>10:cv2.circle(img, center, 5, (0,0,255), -1)cv2.circle(img, center, int(radius), (0,0,255), 2)cv2.imshow("my window",img)k = cv2.waitKey(1)if k==27:break
img.release()
#cam.release()
cv2.destroyAllWindows()

HSL通道分离见上篇文章OpenCV学习四:TrackBar控件(滑动条)
好啦给你们补上了

每日“大饼”:
命运恰如潜流 动无常则 进止难期

OpenCV快速入门五:色彩空间转换相关推荐

  1. OpenCV快速入门篇(Python实现)

    OpenCV快速入门篇(Python实现) 转载自:https://blog.csdn.net/feilong_csdn/article/details/82750029 本系列python版本:py ...

  2. Opencv快速入门(C++版),新手向

    Opencv快速入门(C++版) 前言 1.图像的读取与显示 所使用的API接口: 代码演示: 2.图像色彩空间转换 所使用的API接口: 代码演示: 3.图像对象的创建与赋值 所使用的API接口: ...

  3. opencv快速入门人脸检测与人脸识别

    让"它"认得你 --利用opencv快速入门人脸检测与人脸识别 opencv,顾名思义"开源,计算机视觉".OpenCV就是这样的一个特殊的框架,一群大牛然绕自 ...

  4. opencv快速入门—键盘响应操作

    贾志刚老师-opencv基于c++快速入门基础30讲 本节课程中主要讲解利用键盘实现图像处理过程的便捷操作,如:键盘按下1,图像变成灰度图像:键盘按下2,图像变成hsv色彩空间的图像:键盘按下3,图像 ...

  5. opencv学习四:色彩空间转换

    一.常见的色彩空间 RGB颜色空间 RGB(red,green,blue)颜色空间最常用的用途就是显示器系统,彩色阴极射线管,彩色光栅图形的显示器 都使用R.G.B数值来驱动R.G.B 电子枪发射电子 ...

  6. Flutter快速入门 五步搞定Flutter环境配置

    Flutter是什么? Flutter是一款移动应用程序SDK,一份代码可以同时生成iOS和Android两个高性能.高保真的应用程序. Flutter目标是使开发人员能够交付在不同平台上都感觉自然流 ...

  7. OpenCV Java入门五 结合摄像头识脸和拍照

    随着我们对环境.Mat基本使用越来越熟练.Java Swing也逐步熟悉了起来.今天我们开始进入OpenCV驱动摄像头的几个使用场景. 环境准备 准备好一个USB外接摄像头,我这边使用的有两种,一种是 ...

  8. OpenCV 之 cvCvtColor (色彩空间转换)

    cvCvtColor( img, img_yuv, CV_BGR2YCrCb ); // 色彩空间转换 img 和 img_yuv 均为CvImage 类型 方法作用就是: 将img图像转换为img_ ...

  9. OpenCV快速入门一:图片读取保存

    一:OpenCV介绍 OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux.Windows.Android和Mac OS操作系统上. [1] ...

最新文章

  1. [转]Asp.NET生成静态页面并分页
  2. android筛选cookie,服务器无法从Android手机识别Cookie
  3. Jenkins+Github持续集成
  4. git项目比对_Git实战之Git对比SVN
  5. new调用函数,new具体做了什么?
  6. oracle_sid只能有一个吗_第一次考教资!这些问题你都了解了吗?
  7. 会计用计算机很快是,40个超实用电脑快捷键,老会计都在用!
  8. Jquery Ajax方法传值到action
  9. 为什么现在物质越来越丰富,人的幸福感反而越来越低?
  10. Oracle增量跟新
  11. java servlet ajax_javaweb中ajax请求后台servlet(实例)
  12. node 版本管理器 之 nvm 安装与使用
  13. 面试题-C++软件/客户端开发
  14. Java基础:java线程状态
  15. 向量点乘(内积)和叉乘(外积、向量积)概念及几何意义解读
  16. JavaScript--键盘控制div移动
  17. latex 如何在overleaf中插入算法伪代码
  18. R语言中敏感性和特异性、召回率和精确度作为选型标准的华夫图案例
  19. 12-Java 继承抽象类代码块(详解~)
  20. 怎么查看各进程分别占用多少服务器内存?

热门文章

  1. 函函函函函函函函函函函数——two
  2. 链塔智库|区块链产业要闻及动态周报(2021年8月第3周)
  3. 数码管显示“0~F”的共阳共阴数码管编码表
  4. 音乐推荐-3张新碟《雪狼》+《馨馨醉》+《光》
  5. mqtt - github上的TT3工程编译
  6. BM46 最小的K个数
  7. 循环事件绑定和原型的应用
  8. opencv存入数据库图片入门笔记
  9. 使用canvas画美队盾牌
  10. 虚拟机上无法运行ubuntu自带的gazebo仿真器报VMware: vmw_ioctl_command error 无效的参数