Advertisement

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

阅读量:

      • 一、光和电磁波谱

      • 二、彩色模型

          • 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)的关系可见下式描述:
λ=c/v式中c是光速(2.998×10^8m/s)。电磁波谱的各个分量的能量由下式给出:
E=hv式中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]中。
先定义:max = max(R,G,B) \ \ \ \ \ min = min(R,G,B)
① 色调H,范围 [0,360]
在这里插入图片描述
② 饱和度S,范围 [0,1]
a) max = 0
S = 0b) max \neq 0
S=(max-min)/max

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

4.从HSV到RGB的彩色转换

其中H的取值范围为[0,360],S、V、R、G、B的取值范围为[0,1]
h_{i}\equiv \left\lfloor {\frac {h}{60}}\right\rfloor {\pmod {6}}f={\frac {h}{60}}-h_{i}p=v\times (1-s)\,q=v\times (1-f\times s)\,t=v\times (1-(1-f)\times s)\,
对于每个颜色向量 (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转灰度图像

使用不同的算法,会得到不同的灰度图像,例如若要查看红色在图像的分布情况,可使用:
Gray = 1×R + 0×G + 0×B 从上式可知,选择不同的系数,可得到不同的灰度图像,目前常使用下面的一个心理学公式:
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色彩空间

全部评论 (0)

还没有任何评论哟~