目录

  • 1 OpenCV入门
    • 1.1 如何使用
    • 1.2 图像读入、显示与保存
  • 2 图像处理基础
    • 2.1 图像处理入门基础
    • 2.2 像素处理
    • 2.3 numpy访问像素
    • 2.4 获取图像属性
    • 2.5 感兴趣区域ROI
    • 2.6 通道操作
  • 3 图像运算
    • 3.1 图像加法
    • 3.2 图像融合
    • 3.3 位平面分解
    • 3.4 图像加密和解密
    • 3.5 数字水印
  • 4 色彩空间类型转换
    • 4.1 色彩类型转换
  • 5 几何变换
    • 5.1 图像缩放
    • 5.2 图像翻转
  • 6 阈值处理
    • 6.1 阈值理论知识
    • 6.2 阈值处理实践
  • 7 图像平滑处理
    • 7.1 均值滤波
    • 7.2 方框滤波
    • 7.3 高斯滤波
    • 7.4 中值滤波
  • 8 形态学操作
    • 8.1 图像腐蚀
    • 8.2 图像膨胀
    • 8.3 开运算
    • 8.4 闭运算
    • 8.5 梯度运算
    • 8.6 礼帽操作
    • 8.7 黑帽图像处理
  • 9 图像梯度
    • 9.1 Sobel理论基础
    • 9.2 Sobel算子及函数使用
    • 9.3 Scharr算子及函数使用
    • 9.4 Sobel算子和Scharr算子的比较
    • 9.5 Laplacian算子及函数使用
  • 10 canny边缘检测
    • 10.1 Canny边缘检测原理
    • 10.2 Canny函数及使用
  • 11 图像金字塔
    • 11.1 理论基础
    • 11.2 pyrDown函数及使用
    • 11.3 pyrUp函数及使用
    • 11.4 采样可逆性的研究
    • 11.5 拉普拉斯金字塔
  • 12 图像轮廓
    • 12.1 图像轮廓操作
  • 13 直方图
    • 13.1 直方图的概念
    • 13.2 绘制直方图
    • 13.3 使用OpenCV统计直方图
    • 13.4 绘制OpenCV统计直方图
    • 13.5 使用掩膜的直方图
    • 13.6 掩膜原理及演示
    • 13.7 直方图均衡化原理
    • 13.8 直方图均衡化函数equalizeHist
    • 13.9 subplot函数的使用
    • 13.10 matplotlib.pyplot.imshow函数的使用
    • 13.11 直方图均衡化对比
  • 14 傅里叶变换
    • 14.1 傅里叶变换的理论基础
    • 14.2 numpy实现傅里叶变换
    • 14.3 numpy实现逆傅里叶变换
    • 14.4 高通滤波演示
    • 14.5 OpenCV实现傅里叶变换
    • 14.6 OpenCV实现逆傅里叶变换
    • 14.7 低通滤波示例
色彩类型转换


                                       

 

 

 
 

20级人工智能1 2

 
 

 

 

 

 

 
 

色彩空间类型转换

 
 

教学目的及要求

 
 

了解色彩空间基础,掌握类型转换函数

 
 

 

 
 

色彩类型转换函数

 
 

 

 
 

HSV色彩空间、alpha通道

 
 

 

 
 

讲授法、项目化教学法

 
 

      

 
 

计算机、Anaconda软件

 
 

      

 

 

教学过程及内容

 
 

见下

 

 

基础:

RGB图像是一种常见的色彩空间类型,除此之外还有一些其他的色彩空间,比较常见的包括GRAY色彩空间(灰度图像)、XYZ色彩空间、YCrCb色彩空间、HSV色彩空间、HLS色彩空间、CIEL*a*b*色彩空间、CIEL*u*v*色彩空间、Bayer色彩空间。每个色彩空间都有自己擅长的处理问题的领域,因此,为了更方便地处理某个具体问题,就要用到色彩空间类型转换。

色彩空间类型转换就是指,将图像从一个色彩空间转换到另外一个色彩空间。

色彩空间也称为颜色空间、彩色空间、颜色模型、彩色模型、色彩模型等。

4.1GRAY色彩空间

GRAY(灰度图像)通常指8位灰度图,其具有256个灰度级,像素值的范围为【0-255

Gray=0.299R+0.587G+0.114B

Gray=R+G+B/3

 

4.2类型转换函数

Dst=cv2.cvtColor(src,code)

 

a=cv2.imread("lenacolor.png",-1)
aa=cv2.imread("lena256.bmp",-1)
b=cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)#BGR
图像转灰度图像
c=cv2.cvtColor(a,cv2.COLOR_BGR2RGB)#BGR
图像转RGB图像
d=cv2.cvtColor(aa,cv2.COLOR_GRAY2BGR)#
灰度值转换成BGR图像
print(d.shape)
cv2.imshow("a",a)
cv2.imshow("BGR2GRAY",b)
cv2.imshow("BGR2RGB",c)
cv2.imshow("GRAY2BGR",d)
cv2.waitKey()
cv2.destroyAllWindows()
 
通过数组观察转换效果
例4.1将BGR图像转换为灰度图像

Gray=0.299R+0.587G+0.114B

#4.1BGR图像转换为灰度图像
import cv2
import numpy as np
img=np.random.randint(0,256,size=[2,4,3],dtype=np.uint8)
rst=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print("img=\n",img)
print("rst=\n",rst)
print("
像素点(1,0)直接计算得到的值=",
      img[1,0,0]*0.114+img[1,0,1]*0.587+img[1,0,2]*0.299)
print("
像素点(1,0)使用公式cv2.cvtColor()转换值=",rst[1,0])

print(img[1,0,0])
print(img[1,0,1])
print(img[1,0,2])
 
运行结果:
img=
 [[[ 56  98  47]
  [201 140 198]
  [246 255 167]
  [108 176 148]]
 
 [[ 76  27 104]
  [121 115 129]
  [163   7 136]
  [249  93 123]]]
rst=
 [[ 78 164 228 160]
 [ 56 120  63 120]]
像素点(1,0)直接计算得到的值= 55.608999999999995
像素点(1,0)使用公式cv2.cvtColor()转换值= 56
76
27
104
 
#4.2将灰度图像转换为BGR图像
import cv2
import numpy as np
img=np.random.randint(0,256,size=[2,4],dtype=np.uint8)
rst=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
print("img=\n",img)
print("rst=\n",rst)
 
运行结果:
img=
 [[237  60 217  91]
 [113  41 236 166]]
rst=
 [[[237 237 237]
  [ 60  60  60]
  [217 217 217]
  [ 91  91  91]]
 
 [[113 113 113]
  [ 41  41  41]
  [236 236 236]
  [166 166 166]]]
上述程序进一步印证了,当图像由GRAY色彩空间转换到RGB/BGR色彩空间时,最终所有通道的值都是相同。
R=Gray
G=Gray
B=Gray
 
 
例4.3将图像在BGR和RGB模式之间相互转换
import cv2
import numpy as np
img=np.random.randint(0,256,size=[2,4,3],dtype=np.uint8)
rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
bgr=cv2.cvtColor(rgb,cv2.COLOR_RGB2BGR)
print("img=\n",img)
print("rgb=\n",rgb)
print("bgr=\n",bgr)
 
运行结果:
img=
 [[[ 24 141  13]
  [201  62 193]
  [146  85 152]
  [ 81 237   4]]
 
 [[ 82 131 106]
  [ 59 199  42]
  [141 195 122]
  [189 153 193]]]
rgb=
 [[[ 13 141  24]
  [193  62 201]
  [152  85 146]
  [  4 237  81]]
 
 [[106 131  82]
  [ 42 199  59]
  [122 195 141]
  [193 153 189]]]
bgr=
 [[[ 24 141  13]
  [201  62 193]
  [146  85 152]
  [ 81 237   4]]
 
 [[ 82 131 106]
  [ 59 199  42]
  [141 195 122]
  [189 153 193]]]
从程序可以看到,在RGB和BGR模式之间相互转换时,R通道和B通道的位置发生了交换。
 
图像处理实例
#4.4 将图像在BGR模式和灰度图像之间相互转换
#RGB<->GRAY
import cv2
lena=cv2.imread("lenacolor.png")
gray=cv2.cvtColor(lena,cv2.COLOR_BGR2GRAY)
rgb=cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)
#==========
打印shape============
print("lena.shape=",lena.shape)
print("gray.shape=",gray.shape)
print("rgb.shape=",rgb.shape)
#==========
显示效果============
cv2.imshow("lena",lena)
cv2.imshow("gray",gray)
cv2.imshow("rgb",rgb)
cv2.waitKey()
cv2.destroyAllWindows()
 
#4.5将图像从BGR模式转换为RGB模式
import cv2
lena=cv2.imread("lenacolor.png")
rgb = cv2.cvtColor(lena, cv2.COLOR_BGR2RGB)
cv2.imshow("lena",lena)
cv2.imshow("rgb",rgb)
cv2.waitKey()
cv2.destroyAllWindows()
4.4HSV色彩空间
HSV色彩空间从心理学和视觉的角度出发,提出人眼的色彩知觉主要包含三要素:
H:色调(Hue,也称为色相)
S:饱和度(Saturation)
V:亮度(Value)
1.色调
在HSV色彩空间中,色调H的取值范围为【0,360】,8位图像内每个像素点所能表示的灰度级有28=256个,所有在8位图像内表示HSV图像时,要把色调的角度值映射到【0,255】范围内,在OpenCV中,可以直接把色调的角度值除以2,得到【0,180】之间的值,以适应8位二进制(256个灰度级)的存储和表示范围。
 
色调值及对应颜色

                           

色调值(度)
颜色
0
红色
60
黄色
120
绿色
180
青色
240
蓝色
300
品红色
 

 

OPENCV中,将色调值除以2之后,会得到色调值与对应的颜色

                           

色调值(度)
颜色
0
红色
30
黄色
60
绿色
90
青色
120
蓝色
150
品红色

 

2.    饱和度

饱和度值的范围是【0,1

灰度颜色所包含的RGB的成分是相等的,相当于一种极不饱和的颜色,所以,灰度颜色的饱和度值是0.

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

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

3.    亮度V

亮度的范围都是【0,1】,同样,亮度值在OpenCV内也将值映射到【0,255】范围内。

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

 

#4.6OpenCV中,测试RGB色彩空间中不同颜色的值转换到HSV色彩空间后的对应值
import cv2
import numpy as np
#=========
测试下OpenCV中蓝色的HSV模式值=============
imgBlue=np.zeros([1,1,3],dtype=np.uint8)
imgBlue[0,0,0]=255
Blue=imgBlue
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]]]
 
4.4.3标记指定颜色
1.     通过inRange函数锁定特定值
Cv2.inRange()来判断图像内像素点的像素值是否在指定的范围内,其语法格式为:
Dst=cv2.inRange(src,lowerb,upperb)
说明:
dst表示输出结果,大小和src一致
src表示要检查的数组或图像
lowerb表示范围下界
upperb表示范围上界
返回值dst与src等大小,其值取决于src中对应位置上的值是否处于区间[lowerb,upperb]内:
如果src值处于该指定区间内,则dst中对应位置上的值为255。
如果src值不处于该指定区间内,则dst中对应位置上的值为0。
 
#4.7使用函数cv2.inRange()将某个图像内的在[100,200]内的值标注出来
import cv2
import numpy as np
img=np.random.randint(0,256,size=[5,5],dtype=np.uint8)
min=100
max=200
mask = cv2.inRange(img, min, max)
print("img=\n",img)
print("mask=\n",mask)
 
运行结果:
img=
 [[143 206 226  68 237]
 [ 48   0 216 122  60]
 [109 108  47  50  26]
 [232 232   0  20 216]
 [ 79 233  18 188 246]]
mask=
 [[255   0   0   0   0]
 [  0   0   0 255   0]
 [255 255   0   0   0]
 [  0   0   0   0   0]
 [  0   0   0 255   0]]
 
说明:在100-200内的值标记为255,不在100-200范围内的值标记为0.
 
#4.8正常显示某个图像内的感兴趣区域(ROI),而将其余区域显示为黑色
import cv2
import numpy as np
img=np.ones([5,5],dtype=np.uint8)*9
mask =np.zeros([5,5],dtype=np.uint8)
mask[0:3,0]=1
mask[2:5,2:4]=1
roi=cv2.bitwise_and(img,img, mask= mask)
print("img=\n",img)
print("mask=\n",mask)
print("roi=\n",roi)
 
显示特定颜色值:
在实际提取颜色时,往往不是提取一个特定的值,而是提取一个颜色区间。例如在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]之间
 
#4.9分别提取OpenCVlogo图像内的红色、绿色、蓝色。
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()
运行结果:

 
标记肤色
肤色范围划定为:
色调值在【5,170】之间
饱和度值在【25,166】之间
#4.10 提取一副图像内的肤色部门
import cv2
img=cv2.imread("lesson2.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v=cv2.split(hsv)
minHue=5
maxHue=170
hueMask=cv2.inRange(h, minHue, maxHue)
minSat=25
maxSat=166
satMask = cv2.inRange(s, minSat, maxSat)
mask = hueMask & satMask
roi = cv2.bitwise_and(img,img, mask= mask)
cv2.imshow("img",img)
cv2.imshow("ROI",roi)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果:


实现艺术字效果:
保持H通道和S通道的值不变,而将V通道的值都调整为255,即设置为最亮,观察得到的艺术效果。
 
#4.11调整HSV色彩空间内V通道的值,观察其处理结果
import cv2
img=cv2.imread("barbara.bmp")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v=cv2.split(hsv)
v[:,:]=255
newHSV=cv2.merge([h,s,v])
art = cv2.cvtColor(newHSV, cv2.COLOR_HSV2BGR)
cv2.imshow("img",img)
cv2.imshow("art",art)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果:


 
4.5alpha通道
在RGB色彩空间三个通道的基础上,还可以加上一个A通道,也叫alpha通道,表示透明度,这种4个通道的色彩空间被称为RGBA色彩空间,PNG图像是一种典型的4通道图像,alpha通道的赋值范围是【0,1】,或者【0,255】,表示从透明到不透明
 
#4.12编写一个程序,分析alpha通道的值
import cv2
import numpy as np
img=np.random.randint(0,256,size=[2,3,3],dtype=np.uint8)
bgra = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
print("img=\n",img)
print("bgra=\n",bgra)
b,g,r,a=cv2.split(bgra)
print("a=\n",a)
a[:,:]=125
bgra=cv2.merge([b,g,r,a])
print("bgra=\n",bgra)
运行结果:
img=
 [[[151  79 170]
  [ 60 237 101]
  [127 193 248]]
 
 [[ 67  51 190]
  [180  41 147]
  [ 44 100  41]]]
bgra=
 [[[151  79 170 255]
  [ 60 237 101 255]
  [127 193 248 255]]
 
 [[ 67  51 190 255]
  [180  41 147 255]
  [ 44 100  41 255]]]
a=
 [[255 255 255]
 [255 255 255]]
bgra=
 [[[151  79 170 125]
  [ 60 237 101 125]
  [127 193 248 125]]
 
 [[ 67  51 190 125]
  [180  41 147 125]
  [ 44 100  41 125]]]
 
#4.13编写一个程序,对图像的alpha通道进行处理
import cv2
img=cv2.imread("lenacolor.png")
bgra = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
b,g,r,a=cv2.split(bgra)
a[:,:]=125
bgra125=cv2.merge([b,g,r,a])
a[:,:]=0
bgra0=cv2.merge([b,g,r,a])
cv2.imshow("img",img)
cv2.imshow("bgra",bgra)
cv2.imshow("bgra125",bgra125)
cv2.imshow("bgra0",bgra0)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.imwrite("bgra.png", bgra)
cv2.imwrite("bgra125.png", bgra125)
cv2.imwrite("bgra0.png", bgra0)