file: studyyuv.txt
name: 深入學習yuv色彩模型
author: zyl910
version: v1.1
updata: 2006-5-28
最近突然又對圖形學有了興趣,翻出了多年前學習圖形學的筆記,感觸良多。於是將它們整理好發了上來。
一、基礎
rgb轉yuv的轉換是這樣的:
[y] = [ 0.299 0.587 0.114] [r]
[u] = [-0.148 -0.289 0.437] * [g]
[v] = [ 0.615 -0.515 -0.100] [b]
yuv轉rgb的轉換是這樣的:
[r] = [1 0 1.140] [y]
[g] = [1 -0.395 -0.581] * [u]
[b] = [1 2.032 0 ] [v]
二、那些變換係數是如何推導出來的?
最開始,我是想找乙個rgb與yuv轉換的快速演算法,於是開始研究它的係數。
2.1 yuv轉rgb
最先以yuv轉rgb為突破口。注意在轉換矩陣中有兩個0,所以可以去掉一次乘法:
b = y + 2.032*u
r = y + 1.140*v
利用「y = 0.299*r + 0.587*g + 0.114*b」這個事實來推導g:
g = (y - 0.299*r - 0.114*b) / 0.587
將b、r的計算公式代入並化簡:
g = [y - 0.299*(y + 1.140*v) - 0.114*(y + 2.032*u)] / 0.587
= [y - (0.299*y + 0.299*1.140*v) - (0.114*y + 0.114*2.032*u)] / 0.587
= [(y - 0.299*y - 0.114*y)- 0.299*1.140*v - 0.114*2.032*u] / 0.587
= [(1 - 0.299 - 0.114)*y - 0.299*1.140*v - 0.114*2.032*u] / 0.587
= (0.587*y - 0.299*1.140*v - 0.114*2.032*u) / 0.587
= y + (-0.299*1.140*v - 0.114*2.032*u) / 0.587
= y - (0.299*1.140 / 0.587)*v - (0.114*2.032 / 0.587)*u
= y - (0.114*2.032 / 0.587)*u - (0.299*1.140 / 0.587)*v
= y - 0.394630*u - 0.580681*v
正好與yuv轉rgb的係數符合。
完整的轉換公式:
b = y + 2.032*u
r = y + 1.140*v
g = y - (0.114*2.032 / 0.587)*u - (0.299*1.140 / 0.587)*v
2.2 rgb轉yuv
從分析yuv轉rgb時,我們發現了兩個關鍵係數——與u有關的2.032 和 與v有關的1.140。所以我們拿它們去乘rgb轉yuv轉換矩陣的係數試試:
u: 2.032 * [-0.148 -0.289 0.437] = [-0.300736 -0.587248 0.887984]
v: 1.140 * [ 0.615 -0.515 -0.100] = [ 0.701100 -0.587100 -0.114000]
觀察這些係數,發現有兩個特點:
1.那些負數係數與「彩色轉灰度」係數(0.299、0.587、0.114)很相似。
2.那個正數係數 正好等於 兩個負數係數之和的絕對值。
所以我們可以將u、v部分的轉換矩陣看成這個樣子:
u: (1 / 2.032) * [ -0.299 -0.587 1-0.114]
v: (1 / 1.140) * [1-0.299 -0.587 -0.114]
完整的轉換公式:
[y] = [ 0.299 0.587 0.114 ] [r]
[u] = [( -0.299)/2.032 (-0.587)/2.032 (1-0.114)/2.032] * [g]
[v] = [(1-0.299)/1.140 (-0.587)/1.140 ( -0.114)/1.140] [b]
用矩陣計算「rgb轉yuv」很慢,我們可根據「yuv轉rgb」逆推:
y = 0.299*r + 0.587*g + 0.114*b
u = (1 / 2.032)*(b-y)
v = (1 / 1.140)*(r-y)
2.3 小結
所謂的yuv色彩模型是由0.299、0.587、0.114、2.032、1.140這五個數字定義出來的,非常簡潔、精巧。但是這還不是最精巧的,ycbcr完全是由0.299、0.587、0.114這三個數字定義出來的,詳見《深入學習ycbcr色彩模型》。
三、整數演算法
先將前面的成果列出來。
rgb轉yuv:
y = 0.299*r + 0.587*g + 0.114*b
u = (1 / 2.032)*(b-y)
v = (1 / 1.140)*(r-y)
yuv轉rgb:
b = y + 2.032*u
r = y + 1.140*v
g = y - (0.114*2.032 / 0.587)*u - (0.299*1.140 / 0.587)*v
可以看出,u、v、r、b 的計算就是用乘法縮放數值,完全可以陣列查表。
至於y的計算,請參考《彩色轉灰度演算法徹底學習》。
唯一麻煩一點的是g,因為它有兩個乘法,直接整數查表恐怕不精確。所以可以考慮將數值縮放65536倍(16位精度)。
大概是這樣:
y = (r*19595 + g*38469 + b*7472) >> 16
u = yuv_b2u[0x100 + b - y]
v = yuv_r2v[0x100 + r - y]
b = y + yuv_u2b[0x100 + u]
r = y + yuv_v2r[0x100 + v]
g = y - ((yuv_u2g[0x100 + u] + yuv_v2g[0x100 + v]) >> 16)
UIApplication深入學習
新建乙個任意型別的ios應用工程,加入我們在class prefix輸入是tc,我們可以看到工程中生成乙個類 在main函式中,autoreleasepool 函式中 說明 當應用程式將要入非活動狀態執行,在此期間,應用程式不接收訊息或事件。比如來 了。說明 當應用程式入活動狀態執行,這個剛好跟上面...
深入學習CSS
什麼是css?在之前的這篇文章中已經介紹了初步的介紹,詳細請看 div加css進一步講解了css中的內容,先總結如下圖 其實在實際開發中,我們通常採用是外部樣式的匯入,這樣做的好處是對於很對有同樣設計樣式的頁面可以實現樣式的共享,這樣我們不僅僅可以節省了大量的時間,並且也方便我們可以靈活的呼叫的樣式...
block深入學習
block的宣告和使用看上一節就行了。本章主要講block內部的實現過程及原理。block的定義和函式指標非常相似 對比一下 block定義 void someblock 函式指標定義 void functionpionter void functionname 當然區別還是有的,block的返回型...