原文链接:http://www.juzicode.com/archives/5508

返回Opencv-Python教程

在数字图像中,最常见的彩色模型是RGB模型(红、绿、蓝,在OpenCV中彩色图像组织的顺序是B-G-R,仍然是RGB模型),这种模型是硬件处理的常用模型,比如采集图像的CCD传感器、显示图像的显示器等等,符合描述人类眼睛观察的则是HSV(色度、饱和度、亮度)模型。

1、色彩转换cvtColor()

OpenCV则提供了各种彩色模型(色彩空间)相互转换的接口,比如可以从BGR转换为HSV,HSV转换为BGR,也可以从BGR转换为灰度图。

色彩空间的转换函数cvtColor()的接口形式:

dst=cv2.cvtColor(src, code[, dst[, dstCn]])

src为源图像对象;code是OpenCV中色彩空间定义的宏常量,可以通过colors = [i for i in dir(cv) if i.startswith(‘COLOR_’)]的方法遍历出所有的色彩空间转换的名称,在4.5.2版本中转换方法有274种之多。比较常用的有COLOR_BGR2GRAY、COLOR_GRAY2BGR、COLOR_BGR2HSV、COLOR_BGR2RGB,这些名称都能见名知意。dstCn为目标图像的通道数,如果设置为0,会自动从源图像计算目标图像的通道数。

下面这个例子读取图像后图像默认是BGR色彩空间,分别转换为GRAY和HSV色彩空间:

import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)img1 = cv2.imread('..\\lena.jpg')
img2 = cv2.imread('..\\opencv-logo.png') img_ret1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
print('img_ret1.shape:',img_ret1.shape)
print('img1[161,199]:    ',img1[161,199])
print('img_ret1[161,199]:',img_ret1[161,199])
cv2.imshow('lena-cvtColor',img_ret1)img_ret2 = cv2.cvtColor(img2,cv2.COLOR_BGR2HSV)
print('img_ret2.shape:',img_ret2.shape)
print('img2[100,200]:    ',img2[100,200])
print('img_ret2[100,200]:',img_ret2[100,200])
cv2.imshow('logo-cvtColor',img_ret2)cv2.waitKey(0)

运行结果:

VX公众号: 桔子code / juzicode.com
cv2.__version__: 4.5.2
img_ret1.shape: (512, 512)
img1[161,199]:     [109 105 201]
img_ret1[161,199]: 134
img_ret2.shape: (739, 600, 3)
img2[100,200]:     [  0   0 255]
img_ret2[100,200]: [  0 255 255]

从lena图像的运行结果看,转换为GRAY的图像变成了只有黑白2种颜色也就是灰度图像,从图像的shape属性看这时图像也是单通道的。opencv-log图像经过HSV转换后再显示,看起来“颜色”发生了变化,这是因为HSV变量用imshow显示的效果导致的,并不是说其颜色发生了变化,这点也可以通过再将HSV色彩转换回BGR色彩验证。

2、HSV色彩空间

HSV色彩空间通常用一个倒锥形表示:

在这个倒锥型中,小括号中的数值以OpenCV CV_8U类型的数据为例。从下往上的红色直线表示亮度V,越往上表示的亮度越大,OpenCV中的取值范围是0~255;从圆心往外的半径是饱和度V,表示的是颜色的纯度,越远离圆心值越大,取值范围是0~255;在水平截面上的圆的角度表示色度H,因为CV_8U类型的数值表示范围到不了360,在OpenCV中的取值范围实际为是0~180(等于圆的角度除以2),其中红色的色度为0,绿色的色度为120°,OpenCV中的数值为60,蓝色的色度为240°,OpenCV中的数值为120。

BGR转换为HSV的方法为:

V=max(R,G,B)
S=(max(R,G,B)-min(R,G,B))*255/max(R,G,B)
如果max(R,G,B)=0, S=0
如果R=max(R,G,B),H=(G-B)/(R-min(R,G,B))* 30
如果G=max(R,G,B),H=60+(B-R)/(G-min(R,G,B))* 30
如果B=max(R,G,B),H=120+(R-G)/(B-min(R,G,B))* 30
如果R=G=B,H=0; 如果H<0,H=H+360

下面我们以opencv-logo.png为例解释下HSV色彩空间和BGR色彩空间的对应关系:

import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)def show_img(win_name,img,wait_time=0,img_ratio=0.5,is_show=True):if is_show is not True:return rows = img.shape[0]cols = img.shape[1]cv2.namedWindow(win_name, cv2.WINDOW_NORMAL )#cv2.WINDOW_AUTOSIZE)cv2.resizeWindow(win_name,(int(cols*img_ratio),int(rows*img_ratio)))cv2.imshow(win_name,img)#cv2.waitKey(wait_time)img = cv2.imread('..\\opencv-logo.png')
img_ret = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
show_img('logo',img)
h,s,v = cv2.split(img_ret)
show_img('h',h)
show_img('s',s)
show_img('v',v)minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(h)
print('h[20,20]:',h[20,20]) #原图白色
print('h[600,20]:',h[600,20])#原图黑色
print('h[50,300]:',h[50,300])#原图红色
print('h[400,50]:',h[400,50])#原图绿色
print('h[500,500]:',h[500,500])#原图蓝色
print('h: minVal, maxVal=',minVal, maxVal)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(s)
print('s[20,20]:',s[20,20])
print('s[600,20]:',s[600,20])
print('s[50,300]:',s[50,300])
print('s[400,50]:',s[400,50])
print('s[500,500]:',s[500,500])
print('s: minVal, maxVal=',minVal, maxVal)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(v)
print('v[20,20]:',v[20,20])
print('v[600,20]:',v[600,20])
print('v[50,300]:',v[50,300])
print('v[400,50]:',v[400,50])
print('v[500,500]:',v[500,500])
print('v: minVal, maxVal=',minVal, maxVal)cv2.waitKey(0)

运行结果:

cv2.__version__: 4.5.2
h[20,20]: 0
h[600,20]: 0
h[50,300]: 0
h[400,50]: 60
h[500,500]: 120
h: minVal, maxVal= 0.0 120.0
s[20,20]: 0
s[600,20]: 0
s[50,300]: 255
s[400,50]: 255
s[500,500]: 255
s: minVal, maxVal= 0.0 255.0
v[20,20]: 255
v[600,20]: 0
v[50,300]: 255
v[400,50]: 255
v[500,500]: 255
v: minVal, maxVal= 0.0 255.0

这个例子中用到了minMaxLoc()方法,可以计算出图像中的最小和最大值,这幅图像中色度H最大的是120对应的是蓝色。通过对比h分量和原图,原图的红色区域几乎是黑色,正好对应红色的色度值为0,原图的绿色区域稍暗,蓝色区域最亮,对应了绿色的色度值为60,蓝色的色度值为120,我们也可以在原图的红绿蓝3个区域中分别找3个像素点打印出H的值:

h[50,300]: 0    #红色像素
h[400,50]: 60   #绿色
h[500,500]: 120 #蓝色

对比s分量和原图,原图中红绿蓝三个区域对应的s分量都为最亮的白色,而其他区域都为最暗的黑色,因为红绿蓝3个区域对应的颜色非常“纯”,纯粹到只有三原色中的其中一种颜色,而白色区域BGR三色都为255,每种颜色都有,所以是最“不纯”的,这样其S值就为0,而文字部分的黑色区域其S值也为0。

对比v分量和原图,R、G、B三色中谁的值最大,表示的就是V的值,白色区域和红绿蓝区域都有一个分量的值为255,所以V的值就为255,而文字部分的黑色区域其V值也为0。

原文链接:http://www.juzicode.com/archives/5508

扩展阅读:

  1. Opencv-Python教程

OpenCV-Python教程:色彩空间变换(cvtColor)相关推荐

  1. OpenCV Python教程(3)(4)(5): 直方图的计算与显示 形态学处理 初级滤波内

    OpenCV Python教程(3.直方图的计算与显示) 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途 ...

  2. OpenCV Python教程(2、图像元素的访问、通道分离与合并)

    OpenCV Python教程之图像元素的访问.通道分离与合并 转载请详细注明原作者及出处,谢谢! 访问像素 像素的访问和访问numpy中ndarray的方法完全一样,灰度图为: [python] v ...

  3. OpenCV Python教程(1、图像的载入、显示和保存)

    本文是OpenCV  2 Computer Vision Application Programming Cookbook读书笔记的第一篇.在笔记中将以Python语言改写每章的代码. PythonO ...

  4. opencv python教程简书_Python-OpenCV —— 基本操作一网打尽

    OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.MacOS操作系统上.它轻量级而且高效--由一系列 C 函数和少量C++类构成,同时提供了Pyt ...

  5. opencv python教程简书_OpenCV-Python系列二:常用的图像属性

    对于图像,我们经常需要知道关于图像的特殊属性,比如宽度,高度,面积,像素点数目等等,那么在opencv-python中,这些信息如何获取呢? 本文结构: 1.基本图像属性 2. 对于opencv中的特 ...

  6. opencv python教程-OpenCV4 Python 最新中文版官方教程来了(附下载)

    教程简介 OpenCV 是计算机视觉中经典的专用库,然而其中文版官方教程久久不来.近日,一款最新 OpenCV4.1 版本的完整中文版官方教程出炉,读者朋友可以更好的学习了解 OpenCV 相关细节. ...

  7. opencv python教程简书_OpenCV-Python教程:28.模板匹配

    理论 模板匹配是在一个大图里搜索和找模板图像位置的方法.OpenCV有个函数cv2.matchTemplate()来做这个.它吧模板图像在输入图像上滑动,对比模板和在模板图像下的输入图像块.它返回了一 ...

  8. OpenCV+python:色彩空间转换及色彩通道的分离和合并

    1,源代码: import cv2 as cv import numpy as npdef color_space_demo(image): #色彩转换gray = cv.cvtColor(image ...

  9. OpenCV Python教程系列

    参考: OpenCV - sunny2038的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/sunny2038/article/category/904451

  10. opencv python教程简书_OpenCV-Python教程:27.图像转换

    理论 傅里叶变换用来分析多种过滤器的频率特征.对于图片,2D离散傅里叶变换(DFT)用来找频率范围.一个快速算法叫快速傅里叶变换(FFT)用来计算DFT. 对于正弦信号,x(t) = Asin(2πf ...

最新文章

  1. -16 | 12 等于多少
  2. python模拟登录qq账号密码_最新的Python模拟登陆QQ脚本,一键批量登录,强行过验证!...
  3. 怎样学好python-如何学习 Python
  4. RESTful 规范
  5. 性能测试四十八:Jenkins+Ant+Jmeter系统部署
  6. [设计模式]迪米特法则
  7. 工作290:js日期操作
  8. 学习方向、当前要做的事
  9. 拳王虚拟项目公社:网上比较容易挣到钱方式?虚拟资源项目是赚钱的最佳选择
  10. 【CNN】多角度理解CNN
  11. 电音风靡全球,不了解一下吗?
  12. Solidworks如何导入和使用模板文件
  13. 【树莓派】使用USB摄像头拍照
  14. 大数据和数据挖掘之间,主要有什么关系?
  15. 佳能打印机imageRUNNER系列 2206AD驱动安装
  16. Simpson公式、复化梯形公式、Cotes公式以及Romberg公式
  17. GD32F4(2): 用keil5打开官方评估版demo,编译报错找不到core_cm4.h文件
  18. renren-generator:运行报错java: 找不到符号 符号: 类 Longblob
  19. RISC-V指令集架构------RV32F/RV32D浮点扩展指令集
  20. 7.Python条件语句之if语句——从入门到实践

热门文章

  1. 世界上有没有正五面体?
  2. 软件测试用什么cpu,给你的CPU做体检!主流CPU测试软件使用宝典
  3. 三门峡市新型智慧城市顶层设计方案通过专家评审
  4. smali java_Android逆向——初识smali与java类
  5. Thinkpad E475换装Win7后,网络连接无故中断无法再次连接的问题
  6. vue lic在element-ui中使用阿里巴巴矢量图标库iconfont图标
  7. xmapp教程及扩展
  8. Cisco Packet Tracer 实验教程
  9. codesys 轴程序
  10. 详细船舶信息爬虫教程:船讯网根据MMSI爬取对应船舶属性信息|附python爬虫代码