• RGB图像转换为灰度图像的原理


       RGB彩色图像中,一种彩色由R(红色),G(绿色),B(蓝色)三原色按比例混合而成。

           图像的基本单元是一个像素,一个像素需要3块表示,分别代表R,G,B,如果8为表示一个颜色,就由0-255区分不同亮度的某种原色。

           灰度图像是用不同饱和度的黑色来表示每个图像点,比如用8位 0-255数字表示“灰色”程度,每个像素点只需要一个灰度值,8位即可,这样一个3X3的灰度图,只需要9个byte就能保存

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

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

           根据这个公式,依次读取每个像素点的R,G,B值,进行计算灰度值(转换为整型数),将灰度值赋值给新图像的相应位置,所有像素点遍历一遍后完成转换

    def rgb2gray(img):
        # Y' = 0.299 R + 0.587 G + 0.114 B 
        # https://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
        return np.dot(img[...,:3], [0.299, 0.587, 0.114])

    方法一:
    对于彩色转灰度,有一个很著名的心理学公式:

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

    方法二:

    而实际应用时,希望避免低速的浮点运算,所以需要整数算法。
    注意到系数都是3位精度的没有,我们可以将它们缩放1000倍来实现整数运算算法:

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

    RGB一般是8位精度,现在缩放1000倍,所以上面的运算是32位整型的运算。注意后面那个除法是整数 除法,所以需要加上500来实现四舍五入。
    就是由于该算法需要32位运算,所以该公式的另一个变种很流行:

    Gray = (R*30 + G*59 + B*11 + 50) / 100

    方法三:

    上面的整数算法已经很快了,但是有一点仍制约速度,就是最后的那个除法。移位比除法快多了,所以可以将系数缩放成 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

    另一种是 Adobe Photoshop 里的公式
    Adobe RGB (1998) [gamma=2.20]
    Gray = (R^2.2 * 0.2973 + G^2.2 * 0.6274 + B^2.2 * 0.0753)^(1/2.2)

    该方法运行速度稍慢,但是效果很好。

    还有就是 平均值方法

    GRAY = (RED+BLUE+GREEN)/3

    (GRAY,GRAY,GRAY ) 替代 (RED,GREEN,BLUE)

  • 相关阅读:
    621
    Java里的日期和时间学习
    [置顶] 宏扩展和参数扫描
    android 按字母搜索
    使用Eclipse EE开发web项目
    免解压版的Mysql的启动脚本,并且执行导入(windows)
    高焕堂《android从程序员到架构师之路》 YY讲坛直面大师学习架构设计
    Android 计时与倒计时
    poj 1564 Sum It Up | zoj 1711 | hdu 1548 (dfs + 剪枝 or 判重)
    字符型驱动程序的结构框架
  • 原文地址:https://www.cnblogs.com/youxin/p/15733826.html
Copyright © 2020-2023  润新知