概述
- 一、光和电磁波谱
- 二、彩色模型
- 1.RGB彩色模型
- 2.HSV彩色模型
- 3.从RGB到HSV的彩色转换
- 4.从HSV到RGB的彩色转换
- 5.RGB和HSV的互换代码实现(Python+OpenCV)
- 三、灰度图像
- 1.灰度级与灰度图像
- 2.RGB转灰度图像
- 3. RGB转灰度图像代码实现(Python+OpenCV)
更多内容关注公众号:数学的旋律
tb店铺搜:FUN STORE玩物社,专业买手挑选送礼好物
一、光和电磁波谱
1666年,艾萨克牛顿发现,当一束太阳光通过一个玻璃棱镜后,显示的光束不再是白光,而是由一端为紫色而另一段为红色的连续色谱组成。如图1所示,我们感受到的可见光的彩色范围只占电磁波的一小部分。在波谱的一端是无线电波,其波长是可见波长的几十亿倍。波谱的另一端是伽马射线,其波长比可见光小几百万倍。电磁波谱可用波长、频率或能量来描述。波长(
λ
λ
λ)和频率(
v
v
v)的关系可见下式描述:
λ
=
c
/
v
λ=c/v
λ=c/v式中
c
c
c是光速(
2.998
×
1
0
8
m
/
s
2.998×10^8m/s
2.998×108m/s)。电磁波谱的各个分量的能量由下式给出:
E
=
h
v
E=hv
E=hv式中
h
h
h是普朗克常数。
电磁波可视为以波长
λ
λ
λ传播的正弦波,从上面的式子可以看出,能量与频率成正比,因此更高频率(更短波长)的电磁现象的每个光子携带更多的能量。
二、彩色模型
1.RGB彩色模型
在RGB模型中,每种颜色出现在红(Red)、绿(Green)、蓝(Blue)的原色光谱成分中。该模型基于笛卡儿坐标系。在RGB彩色模型中表示的图像由3个分量图像组成,每种原色一幅分量图像。当送入RGB监视器时,这3幅图像在屏幕上混合生成一幅合成的彩色图像。
见图2,为方便起见,假定所有颜色值均已归一化,即R、G和B的所有值都在区间[0,1]中。0表示不发光,1表示完全发光。以(1,0,0)为例,R为1即完全发光,G与B为0即不发光,最终颜色为红色;以(1,1,0)为例,R与G为1即完全发光,B为0即不发光,即红色跟绿色完全发光,蓝色不发光,最终颜色为黄色。
2.HSV彩色模型
通常用以区别不同颜色特性的是明度、色调和饱和度。明度具体表达了无色的强度概念;色调是光波混合中与主波长有关的属性,表示观察者感知的主要颜色,当我们说一个物体是红色、橙色时,指的是其色调;饱和度指的是相对纯净度,或一种颜色混合白光的数量,所加白光越少饱和度越高。色调与饱和度一起称为色度,因此,颜色可用其明度和色度来表征。
HSV(色调、饱和度、明度)彩色模型,正是由这三个分量组成的图像。
3.从RGB到HSV的彩色转换
下式中RGB的值需归一化,即所有值在区间[0,1]中。
先定义:
m
a
x
=
m
a
x
(
R
,
G
,
B
)
m
i
n
=
m
i
n
(
R
,
G
,
B
)
max = max(R,G,B) min = min(R,G,B)
max=max(R,G,B) min=min(R,G,B)
① 色调H,范围 [0,360]
② 饱和度S,范围 [0,1]
a)
m
a
x
=
0
max = 0
max=0
S
=
0
S = 0
S=0b)
m
a
x
≠
0
max neq 0
max=0
S
=
(
m
a
x
−
m
i
n
)
/
m
a
x
S=(max-min)/max
S=(max−min)/max
③ 亮度V,范围 [0,1]
V
=
m
a
x
(
R
,
G
,
B
)
V=max(R,G,B)
V=max(R,G,B)
4.从HSV到RGB的彩色转换
其中
H
H
H的取值范围为[0,360],
S
、
V
、
R
、
G
、
B
S、V、R、G、B
S、V、R、G、B的取值范围为[0,1]
h
i
≡
⌊
h
60
⌋
(
m
o
d
6
)
h_{i}equiv leftlfloor {frac {h}{60}}rightrfloor {pmod {6}}
hi≡⌊60h⌋(mod6)
f
=
h
60
−
h
i
f={frac {h}{60}}-h_{i}
f=60h−hi
p
=
v
×
(
1
−
s
)
p=vtimes (1-s),
p=v×(1−s)
q
=
v
×
(
1
−
f
×
s
)
q=vtimes (1-ftimes s),
q=v×(1−f×s)
t
=
v
×
(
1
−
(
1
−
f
)
×
s
)
t=vtimes (1-(1-f)times s),
t=v×(1−(1−f)×s)
对于每个颜色向量
(
r
,
g
,
b
)
(r, g, b)
(r,g,b)
5.RGB和HSV的互换代码实现(Python+OpenCV)
OpenCV的cvtColor()函数能支持各种彩色模型的转换,其中包括RGB和HSI的转换,部分用法如下:
cv2.cvtColor(src, code)
src为要转换的图片,code为转换的格式,code参数:
1、BGR <=> RGB : COLOR_BGR2RGB、COLOR_RGB2BGR
2、BGRA <=> RGBA :COLOR_BGRA2RGBA、 COLOR_RGBA2BGRA
3、BGR 和 RGB 添加 alpha 通道 : COLOR_BGR2BGRA、COLOR_RGB2RGBA
4、BGRA 和 RGBA 删除 alpha 通道 :COLOR_BGRA2BGR、 COLOR_RGBA2RGB
5、BGR 和 RGB <=> HSV : COLOR_BGR2HSV、COLOR_RGB2HSV、COLOR_HSV2BGR、COLOR_HSV2RGB(转换后H的取值范围为[0,180],S和V的取值范围为[0,255])
现用一张8位的图片01.jpg演示代码:
import cv2
img = cv2.imread('01.jpg') # 获取字节顺序为BGR的图片
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) # 添加 alpha 通道
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # BGR转HSV
img3 = cv2.cvtColor(img2, cv2.COLOR_HSV2RGB) # HSV 转 RGB
img[0][0]
img1[0][0]
img2[0][0]
img3[0][0]
# 显示结果如下:
array([119, 203, 238], dtype=uint8)
array([119, 203, 238, 255], dtype=uint8) # 增加了第4个分量即 alpha 通道
'''
根据上文算法将 BGR 转换成 HSV
H = (G-B) / (max-min) * 60 = (203-119) / (238-119) * 60 = 42.35,H的取值范围在[0,360],需转换到[0,180],得42.35/2 = 21
S = (max-min) / max = (238-119) / 238 = 0.5,0.5 * 255 = 128
V = max(R,G,B) = 238
'''
array([ 21, 128, 238], dtype=uint8)
'''
根据上文算法将 HSV 转换成 RGB
将hsv分别转换到范围[0,180]、[0,1]、[0,1] 得 [21*2, 128/255, 238/255] = [42, 0.502, 0.933]
hi = h/60 mod 6 = 42 / 60 mod 6 = 0
f = h/60 - hi = 42 / 60 - 0 = 0.7
p = v*(1-s) = 0.933*(1-0.502) = 0.4646
q = v*(1-f*s) = 0.933*(1-0.7*0.502) = 0.6051
t = v*(1-(1-f)*s) = 0.933*(1-(1-0.7)*0.502) = 0.7925
因为hi = 0,RGB = [v, t, p] = [0.933, 0.7925, 0.4646],转换到范围[0,255] 得 [238, 202, 118]
'''
array([238, 202, 118], dtype=uint8)
三、灰度图像
1.灰度级与灰度图像
没有颜色的光称为单色光或无色光。单色光的唯一属性是其强度或大小。因为感知单色光的强度从黑色到灰色变化,最后到白色,灰度级一次通常用来表示单色光的强度。
从黑到白的单色光的度量值范围通常称为灰度级,而单色图像通常称为灰度图像。
2.RGB转灰度图像
使用不同的算法,会得到不同的灰度图像,例如若要查看红色在图像的分布情况,可使用:
G
r
a
y
=
1
×
R
+
0
×
G
+
0
×
B
Gray = 1×R + 0×G + 0×B
Gray=1×R+0×G+0×B 从上式可知,选择不同的系数,可得到不同的灰度图像,目前常使用下面的一个心理学公式:
G
r
a
y
=
0.299
×
R
+
0.587
×
G
+
0.114
×
B
(
1
)
Gray = 0.299×R + 0.587×G + 0.114×B (1)
Gray=0.299×R+0.587×G+0.114×B (1)
3. RGB转灰度图像代码实现(Python+OpenCV)
① cv2.imread()实现RGB转灰度
OpenCV的imread()函数能支持各种静态图像文件格式,其中包括RGB转灰度,部分用法如下:
cv2.imread(filename[, flags])
该函数返回的图像格式为BGR,与RGB表示的色彩空间相同,但是字节顺序相反。
filename为图片路径,flags表示用何种方式读取图片,默认为IMREAD_COLOR ,flags参数:
1、IMREAD_COLOR = 1 : 加载彩色图像,最多8位
2、IMREAD_GRAYSCALE = 0 : 以灰度模式加载图像,算法为式(1),最多8位
3、IMREAD_UNCHANGED = -1: 包含alpha通道,可加载8位和16位图像
现用两张8位的图片01.jpg和02.png演示代码:
import cv2
img1 = cv2.imread('01.jpg', cv2.IMREAD_COLOR)
img2 = cv2.imread('01.jpg', cv2.IMREAD_GRAYSCALE) # 转换成灰度图像
img3 = cv2.imread('01.jpg', cv2.IMREAD_UNCHANGED)
img4 = cv2.imread('02.png', cv2.IMREAD_UNCHANGED)
img1[0][0]
img2[0][0:1]
img3[0][0]
img4[0][0]
# 显示结果如下:
array([119, 203, 238], dtype=uint8) # 8位彩色图片,若图片为16位也会转换成8位
array([204], dtype=uint8) # 计算式(1)得 0.299*238+0.587*203+0.114* 119 = 204
array([119, 203, 238], dtype=uint8) # 无alpha通道
array([119, 203, 238, 255], dtype=uint8) # 第4个分量为alpha通道,若图片为16位则可保留16位
② cv2.cvtColor()实现RGB转灰度
OpenCV的cvtColor()函数能支持各种彩色模型的转换,其中包括RGB和灰度的转换,部分用法如下:
cv2.cvtColor(src, code)
src为要转换的图片,code为转换的格式,code参数:
1、BGR => 灰度 : COLOR_BGR2GRAY
现用一张8位的图片01.jpg演示代码:
import cv2
img = cv2.imread('01.jpg') # 获取字节顺序为BGR的图片
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # BGR转灰度
img[0][0]
img1[0][0:1]
# 显示结果如下:
array([119, 203, 238], dtype=uint8)
array([204], dtype=uint8) # 计算式(1)得 0.299*238+0.587*203+0.114* 119 = 204
以上全部内容参考书籍如下:
冈萨雷斯《数字图像处理(第三版)》
HSL和HSV色彩空间
最后
以上就是优雅小白菜为你收集整理的计算机视觉(一):基础篇的全部内容,希望文章能够帮你解决计算机视觉(一):基础篇所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复