2010年9月15日 星期三

BLE WLE Implement and RGB convert to YCbCr(YUV)

看到BLE跟WLE的資料,
所以拿Python來寫看看...
因為主要是對Y做處理,所以要先將RGB轉成YCrCb(YUV)

reference:
  1. 請問 RGB 轉換至 YCbCr (YUV) 的計算公式中如何替換 Cg 的?
    http://forum.slime.com.tw/thread102222.html
  2. [程式] RGB與YUV的色彩轉換
    http://www.wretch.cc/blog/killman/7147165
  3. RGB <--> YUV Conversion Formulas
    http://www.cse.msu.edu/~cbowen/docs/yuvtorgb.html

第一篇的文章提到了一個重點,
當初在寫CA Transform Compress的時候,堅哥有建議我轉YUV,可以降低1/4的資訊量,
可是轉完整個畫面顏色都偏掉了,而那個時候我不清楚為什麼會這樣...
我以為是因為轉換過程的Loss,但實際上RGB轉YCbCr是接近Lossless的。

簡單說,當初我用了Analog的轉換式來運算,
但實際上RGB轉YCbCr有分Analog與Digital,
BT.601與BT.709的轉換式也不同。

YUV是根據人眼對顏色的感知所弄出來的color space,
同時,人眼對於亮度的變化感覺最明顯,
以下列式子為例,綠色占的比例最高,紅色次之,藍色最低,因為人對於綠色的感知程度最高
Ey = 0.299R+0.587G+0.114B
Ecr = 0.713(R - Ey) = 0.500R-0.419G-0.081B
Ecb = 0.564(B - Ey) = -0.169R-0.331G+0.500B
上述是BT.601的參數,而BT.709是針對LCD Display所定出來的建議值。

下面是BLE/WLE的Code,以及RGB與YCbCr的轉換
import Image
im = Image.open("test.jpg")
#print im.format, im.size, im.mode
im.show()

#BLE and WLE Filter
BIL = range(256)
BIL[0:20] = [0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,4,8,12,16,20]
BIL[236:256] = [236,240,244,248,252,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255]

im_array = im.load()
Y601CbCr = im
Y601CbCr_array = Y601CbCr.load()
x,y = im.size
#Convert image from RGB Space to Y601CbCr space
for i in range(x):
for j in range(y):
R = im_array[i,j][0]
G = im_array[i,j][1]
B = im_array[i,j][2]
Y601 = int(R * 0.299 + G * 0.587 + B * 0.114)
Cb = int(R * -0.169 + G * -0.332 + B * 0.500 + 128)
Cr = int(R * 0.500 + G * -0.419 + B * -0.0813 + 128)
Y601CbCr_array[i,j] = (Y601,Cb,Cr)

#BLE and WLE
x,y = Y601CbCr.size
for i in range(x):
for j in range(y):
Y601CbCr_array[i,j] = ( BIL[Y601CbCr_array[i,j][0]],
Y601CbCr_array[i,j][1],
Y601CbCr_array[i,j][2])

#Convert image from Y601CbCr space to RGB Space
x,y = im.size
for i in range(x):
for j in range(y):
Y601 = Y601CbCr_array[i,j][0]
Cb = Y601CbCr_array[i,j][1]
Cr = Y601CbCr_array[i,j][2]
R = int(Y601 + (1.4075 * (Cr - 128)))
G = int(Y601 - (0.3455 * (Cb - 128)) - (0.7169 * (Cr - 128)))
B = int(Y601 + (1.7790 * (Cb - 128)))
im_array[i,j] = (R,G,B)

im.show()

Result:
Orignal
After BLE and WLE 

利用調整曲線讓Y更早截止、飽和,犧牲偏亮與偏暗的細節,
讓畫面看起來對比更高。

點圖可以看原始圖片,原圖是1920x1080的圖片,
上傳之後被縮小了Q.Q


PS.
謹以此文向當初我那難產的CA Transform Compress與堅哥至上敬意...

沒有留言:

張貼留言

Fix msmtp does not work in old ubuntu/debian version

主要是舊版msmtp沒有處理好email header 現在的smtp伺服器會檢查mail header 寄件人跟帳號不一致不給寄 收件人不是合法mail address自然不能寄 #!/bin/bash # Workaround until mtmsp >= 1.8....