我把以前寫過的東西做一個整理,因為時間的關(guān)系,我沒有辦法把每一個細節(jié)都講得非常的詳細,不過我會把大概的原因,和處理的方法,盡量用很精簡的方式,條列整理出來。如果對更深入的原理有興趣,請搜尋過去零散的討論。
一切都要從 ITU-R BT.601 這個"建議"開始說起。 現(xiàn)今的 DVD/VCD/DV 都是遵循 ITU-R BT.601 這個規(guī)格,這個規(guī)格規(guī)定了,模擬影像轉(zhuǎn)數(shù)字時,取樣的方式,儲存的數(shù)據(jù)格式、數(shù)據(jù)范圍等等。 當(dāng)影像轉(zhuǎn)為 MPEG 的時候,RGB 數(shù)據(jù)要轉(zhuǎn)成 MPEG 使用的 YUV 格式。ITU-R BT.601 里面規(guī)定了這個 RGB <-> YUV 的轉(zhuǎn)換式,數(shù)據(jù)范圍 0~255 的 RGB 要轉(zhuǎn)為 YUV 的時候,要先做數(shù)據(jù)范圍的壓縮,把范圍壓縮成 16~235,然后才轉(zhuǎn)成 YUV 儲存起來。然后 MPEG 解壓縮的時候,解出來的 YUV,要做數(shù)據(jù)范圍的擴張,將 Y: 16~235, UV: 16~240 的數(shù)據(jù)擴展為 0~255 的 RGB,也就是還原回原來的 RGB 數(shù)值,然后才能顯示在顯示器的屏幕上。 這個 0~255 RGB -> 16~235 YUV 的過程,就叫做 YC 壓縮。 反過來 16~235 YUV -> 0~255 RGB 的過程就叫做 YC 伸張。 我們可以很清楚地看到,YC 伸張和壓縮要互相搭配,最終顯示出來的結(jié)果才正確。 如果: A. 播放時 1. 轉(zhuǎn) MPEG 的時候沒有做 YC 壓縮,儲存的是 0~255 的 YUV,播放時就不可以做 YC 伸張,否則 0~255 的資料再伸張一次,會變成 -19~278。當(dāng)然,8 bits 的數(shù)據(jù)儲存范圍只能是 0~255,數(shù)據(jù)超出的范圍會被削掉(clipping),整個畫面對比會過強,色彩會崩潰。 2. 轉(zhuǎn) MPEG 的時候有做 YC 壓縮,儲存的是 16~235 的 YUV,播放時就一定要做 YC 伸張,如果不做 YC 伸張,顯示的是 16~235 YUV -> 16~235 RGB。RGB [235,235,235] 在顯示器上看起來不是純白,而會有點灰灰的,[255,255,255] 才是純白。 相同的,[16,16,16] 看起來也不會是純黑,[0,0,0] 才是純黑。 16~235 的 RGB,數(shù)據(jù)范圍(動態(tài)范圍)縮小,對比會變差,色彩黯淡,看上去好像蒙上了一層白紗。 顯示卡的 DirectDraw Overlay,使用硬件的 YUV -> RGB 色彩空間轉(zhuǎn)換,都會遵守 ITU-R BT.601 的建議,認為 MPEG 的 YUV 數(shù)據(jù)范圍應(yīng)該是 16~235,所以都會做 YC 伸張。 所以我們可以得到結(jié)論,當(dāng)轉(zhuǎn)成 MPEG 的時候,一定要確保 YUV 的數(shù)據(jù)范圍是 16~235,這樣在計算機上看、在電視上看,才會看到正確的色彩、對比表現(xiàn)。 所以 B. 壓縮時 1. 如果輸入的 RGB 數(shù)據(jù)范圍是 0~255,轉(zhuǎn) MPEG-2 時就要先做 YC 壓縮,轉(zhuǎn)成 16~235 的 YUV,這樣將來播放時顯示才會正確。 2. 如果輸入的 RGB 數(shù)據(jù)范圍是 16~235,轉(zhuǎn) MPEG-2 時就不能做 YC 壓縮,要直接轉(zhuǎn)成 16~235 的 YUV,這樣將來播放時顯示才會正確。 如果輸入的是 16~235 RGB,轉(zhuǎn) MPEG 時又再做一次 YC 壓縮,數(shù)據(jù)范圍會變成 30~218 YUV,這樣即使將來播放時做 YC 伸張,還是只能伸張到 16~235 的 RGB,結(jié)果還是不對。 那么,重點就是 1. 怎么知道輸入的訊源是 16~235 RGB,還是 0~255 RGB? 2. 怎么知道壓縮的 MPEG 軟件在轉(zhuǎn) RGB -> YUV 的時候會做 YC 壓縮,還是不做 YC 壓縮? |
|