從RGB色轉為灰度色演算法

2021-05-24 13:47:10 字數 2063 閱讀 9170

一、基礎

對於彩色轉灰度,有乙個很著名的心理學公式:

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

但是,雖說上乙個公式是32位整數運算,但是根據80x86體系的整數乘除指令的特點,是可以用16位整數乘除指令來運算的。而且現在32位早普及了(amd64都出來了),所以推薦使用上乙個公式。

三、整數移位演算法

上面的整數演算法已經很快了,但是有一點仍制約速度,就是最後的那個除法。移位比除法快多了,所以可以將係數縮放成 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

常用RGB色值表

常用rgb色值表 淺粉紅 ffb6c1 255,182,193 粉紅 ffc0cb 255,192,203 猩紅 深紅 dc143c 220,20,60 淡紫紅 fff0f5 255,240,245 弱紫羅蘭紅 db7093 219,112,147 熱情的粉紅 ff69b4 255,105,180 ...

RGB顏色與16進製制色以及透明色

劉巨集亮的部落格 rgb顏色與16進製制色以及透明色是我們在開發經常要用到的,不太明白可以花幾分鐘看看 rgb色彩模式是工業界的一種顏色標準,是通過對紅 r 綠 g 藍 b 三個顏色通道的變化以及它們相互之間的疊加來得到各式各樣的顏色的,rgb即是代表紅 綠 藍三個通道的顏色,這個標準幾乎包括了人類...

RGB 色值與十六進製制色值互轉

開發中時常遇到色值轉換問題,記錄下這幾行 方便自己也方便看到此部落格的你。rgb 分別對應紅綠藍三種色值,每個值的取值範圍在 0,255 之間的整數。轉換方法 string hex string.format 02x 02x 02x integer.parseint r integer.parsei...