Bootstrap

图像处理———RGB图色彩格式转灰度图和SUV格式原理及实现

一、RGB转灰度图

重要性:彩色图转灰度图在图像处理中应用非常非常广泛,而且很多算法只对灰度图有效,所以彩色图转灰度是十分关键和重要的。

RGB值和灰度的转换,实际上是人眼对于彩色的感觉到亮度感觉的转换,这是一个心理学问题,有一个著名的公式:

                      Gray = R * 0.299 + G * 0.587 + B * 0.114

我们可以通过这个式子将RGB的数值转化为灰度的数值,但是直接用这个式子的话,计算机当中用浮点数储存,精度太高(小数点后三位了),运算起来会比较慢。另一方面,乘除法也是计算量比较大的运算。
因此,我们可以通过以下方法优化运算速度:

1、整数算法(改善浮点数)

注意到系数都是3位精度,我们可以将它们缩放1000倍,这样系数就都是整数了:

                      Gray = (R*299 + G*587 + B*114 + 500) / 1000

RGB一般是8位精度,现在缩放1000倍,所以上面的运算是32位整型的运算。注意后面那个除法是整数除法,所以需要加上500来实现四舍五入。

2、整数移位算法(改善乘除法)

移位比除法快多了,所以可以将系数缩放成 2的整数幂。
习惯上使用16位精度,2的16次幂是65536,所以这样计算系数:

                      0.299 * 65536 = 19595.264 ≈ 19595
                      0.587 * 65536 + (0.264) = 38469.632 + 0.264 = 38469.896 ≈ 38469
                      0.114 * 65536 + (0.896) =   7471.104 + 0.896 = 7472

可能很多人看见了,我所使用的舍入方式不是四舍五入。四舍五入会有较大的误差,应该将以前的计算结果的误差一起计算进去,舍入方式是去尾法:

写成表达式是:

                      Gray = (R*19595 + G*38469 + B*7472) >> 16

2至20位精度的系数:

                      Gray = (R*1 + G*2 + B*1) >> 2
                      Gray = (R*2 + G*5 + B*1) >> 3
                      Gray = (R*4 + G*10 + B*2) >> 4
                      Gray = (R*9 + G*19 + B*4) >> 5
                      Gray = (R*19 + G*37 + B*8) >> 6
                      Gray = (R*38 + G*75 + B*15) >> 7
                      Gray = (R*76 + G*150 + B*30) >> 8
                      Gray = (R*153 + G*300 + B*59) >> 9
                      Gray = (R*306 + G*601 + B*117) >> 10
                      Gray = (R*612 + G*1202 + B*234) >> 11
                      Gray = (R*1224 + G*2405 + B*467) >> 12
                      Gray = (R*2449 + G*4809 + B*934) >> 13
                      Gray = (R*4898 + G*9618 + B*1868) >> 14
                      Gray = (R*9797 + G*19235 + B*3736) >> 15
                      Gray = (R*19595 + G*38469 + B*7472) >> 16
                      Gray = (R*39190 + G*76939 + B*14943) >> 17
                      Gray = (R*78381 + G*153878 + B*29885) >> 18
                      Gray = (R*156762 + G*307757 + B*59769) >> 19
                      Gray = (R*313524 + G*615514 + B*119538) >> 20

仔细观察上面的表格,这些精度实际上是一样的:3与4、7与8、10与11、13与14、19与20
所以16位运算下最好的计算公式是使用7位精度,比先前那个系数缩放100倍的精度高,而且速度快:

                      Gray = (R*38 + G*75 + B*15) >> 7

其实最有意思的还是那个2位精度的,完全可以移位优化:

                      Gray = (R + (WORD)G<<1 + B) >> 2

(注:部分内容引用这篇博客

3、代码实现

用的 cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)函数

import cv2
import numpy as np

image = cv2.imread('birthday.jpg')
dst = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

cv2.namedWindow('dst',cv2.WINDOW_NORMAL)#因为图像太大加的,让它能在屏幕内显示全
cv2.imshow("dst",dst)

cv2.waitKey(0)

效果如下
原图
转成的灰度图
这张图很好看,是我室友拿ipad pro为母校的云校庆画的生日祝福。

二、RGB转HSV

1.转换颜色空间

在 OpenCV 中有 超过150 种进行颜色空间转换的方法。但是你以后就会发现我们经常用到的也就两种:BGR↔Gray 和 BGR↔HSV。
我们用到的函数是cv2.cvtColor(input_imageflag),其中flag就是转换类型。
对于BGR↔Gray的转换,我们使用的flag就是

                    cv2.COLOR_BGR2GRAY

同样对于BGR↔HSV的转换我们用的flag就是

                   cv2.COLOR_BGR2HSV

2.学习了一个好玩的物体跟踪

现在我们知怎样将一幅图像从 BGR 换到 HSV 了,我们可以利用 一点来提取带有某个特定色的物体。在 HSV 颜色空间中要比在 BGR 空间中更容易表示一个特定颜色。在我们的程序中,我们提取的是一个蓝色的物体。下就是就是我们做的几步:
• 从视频中获取每一帧图像
• 将图像换到 HSV 空间
• 设置 HSV 阀值到蓝色范围。
• 获取蓝色物体,当然我们可以做其他任何我们想做的事,比如:在蓝色物体周围画一个圈。

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while(1):
    #获取每一帧
    ret,frame = cap.read()
    #转换到HSV
    hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
    #设定蓝色的阀值
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
    #根据阀值构建掩模
    mask = cv2.inRange(hsv,lower_blue,upper_blue)
    #对原图和掩模进行位运算
    res = cv2.bitwise_and(frame,frame,mask=mask)
    #显示图像
    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    k = cv2.waitKey(5)&0xFF
    if k == 27:
        break
#关闭窗口
cv2.destroyAllWindows()

推荐一下这个链接 这一部分出自于它,效果如下:
在这里插入图片描述
这个是个动态的颜色跟踪,根据摄像头拍摄到的内容跟踪蓝色,提取出的蓝色的部分效果还不错。

;