计算机视觉(一):基础篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/eeeee123456/article/details/82896954

一、光和电磁波谱

      1666年,艾萨克牛顿发现,当一束太阳光通过一个玻璃棱镜后,显示的光束不再是白光,而是由一端为紫色而另一段为红色的连续色谱组成。如图1所示,我们感受到的可见光的彩色范围只占电磁波的一小部分。在波谱的一端是无线电波,其波长是可见波长的几十亿倍。波谱的另一端是伽马射线,其波长比可见光小几百万倍。电磁波谱可用波长、频率或能量来描述。波长( λ λ )和频率( v v )的关系可见下式描述:
λ = c / v λ=c/v 式中 c c 是光速( 2.998 × 1 0 8 m / s 2.998×10^8m/s )。电磁波谱的各个分量的能量由下式给出:
E = h v E=hv 式中 h h 是普朗克常数。
在这里插入图片描述

图1    电磁波谱    为便于解释,可见光谱已被放大,但请注意,可见光谱是电磁波谱中相当窄的一部分

    电磁波可视为以波长 λ λ 传播的正弦波,从上面的式子可以看出,能量与频率成正比,因此更高频率(更短波长)的电磁现象的每个光子携带更多的能量。



二、彩色模型

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    RGB彩色立方体示意图    沿主对角线的点有从原点的黑点至点(1,1,1)的白色的灰度值
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)
① 色调H,范围 [0,360]
在这里插入图片描述
② 饱和度S,范围 [0,1]
a) m a x = 0 max = 0
S = 0 S = 0 b) m a x 0 max ≠ 0
S = ( m a x m i n ) / m a x S=(max-min)/max

③ 亮度V,范围 [0,1]
V = m a x ( R , G , B ) V=max(R,G,B)

4.从HSV到RGB的彩色转换

其中 H H 的取值范围为[0,360], S V R G B S、V、R、G、B 的取值范围为[0,1]
h i h 60 ( m o d 6 ) h_{i}\equiv \left\lfloor {\frac {h}{60}}\right\rfloor {\pmod {6}} f = h 60 h i f={\frac {h}{60}}-h_{i} p = v × ( 1 s )   p=v\times (1-s)\, q = v × ( 1 f × s )   q=v\times (1-f\times s)\, t = v × ( 1 ( 1 f ) × s )   t=v\times (1-(1-f)\times s)\,
对于每个颜色向量 ( r , g , b ) (r, g, b)
在这里插入图片描述

5.RGB和HSI的互换代码实现(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     从上式可知,选择不同的系数,可得到不同的灰度图像,目前常使用下面的一个心理学公式:
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)

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色彩空间

猜你喜欢

转载自blog.csdn.net/eeeee123456/article/details/82896954