1. 前言
在播放器架構不斷演進的今天,視頻後處理技術正在成為提升用户體驗的關鍵環節。相比傳統的解碼即播,現代播放器越來越多地引入後處理鏈路,通過增強畫質、渲染氛圍等手段,為用户提供更具沉浸感的視聽體驗。
本系列文章將系統介紹我們在播放器視頻後處理模塊中的技術方案與工程實現,涵蓋從效果設計、算法選型,到性能優化和跨平台兼容的全鏈路細節。第一期內容聚焦在兩類核心能力:
- 視頻增強:提升畫面清晰度、對比度與色彩表現,尤其針對暗場、低碼率等場景進行針對性優化;
- 氛圍模式:基於視頻內容實時生成邊緣延展光效,打造更強沉浸感,適配大屏與移動端場景。
本文將着重介紹我們如何在性能受限的設備上實現視頻增強效果,如何結合 GPU/OpenGL、Shader 編程以及平台圖像處理 API 構建高效可控的處理鏈路。後續我們將陸續推出如氛圍模式等視頻後處理文章,敬請期待。
2. 視頻增強(亮度和色彩)
丨2.1 什麼是視頻增強技術
視頻增強技術是指一系列用於改善視頻質量的技術手段,其目的是在不改變原始內容的情況下提升視頻的視覺效果。技術的應用場景包括視頻播放、編輯、傳輸、存儲等領域,常用於提高圖像清晰度、對比度、色彩飽和度等,使觀看者獲得更好的視覺體驗。
丨2.2 常見視頻增強技術
移動端實踐:亮度與色彩增強。針對Android/iOS平台的視頻播放場景,我們重點實現了亮度增強與色彩增強兩項關鍵技術。本文將分享技術落地中的核心方案與優化經驗。
丨2.3 亮度增強
亮度增強效果示意圖(左:原圖 右:增強後)
2.3.1 技術選型
亮度增強是圖像/視頻處理中非常基礎且常見的操作,常見的亮度增強原理可以分為以下幾類,每種方式背後的核心思想略有不同。下面是詳細的分類和解釋:
- 線性亮度增強(線性增益)
原理:RGB整體直接乘以一個大於 1 的係數(或加一個偏移量)。
公式:
color.rgb = color.rgb * gain; // 乘法增強color.rgb = color.rgb + offset; // 加法增強
- 簡而言之,這種做法就是簡單粗暴的在原本的RGB上進行提升,從這裏,可以想到RGB顏色調整後容易出現色偏。
- 那麼我們可能會想到,如果先將RGB轉換為YUV,調節Y 分量,再反變換為 RGB。
公式:
Y = 0.299*R + 0.587*G + 0.114*B;
Y_new = Y * gain;
- 這確實是視頻增強中一種常用且理論上“更穩”的方式,因為它分離了亮度(Y)和色彩(UV / IQ / CbCr)信息。
- 但這種處理方式有一個嚴重的問題,不處理圖像的對比度或中間的關係,且不能保留高光細節(Clipping),也就是調整後,超過範圍[0.0,1.0]的值會被截斷(clamp),造成高光過曝。
- 直方圖均衡(Histogram Equalization)
原理:通過調整像素分佈,讓亮度值均勻分佈在整個區間,從而整體提升視覺亮度。
特點:增強暗部和亮部的對比,對低對比度圖像尤其有效。
實現相對複雜,不常用於實時shader,考慮到其運算複雜性,我們也pass了這種方式。
- Gamma 變換(冪律調整)
原理:使用冪函數對像素進行非線性拉伸。
公式:
color.rgb = pow(color.rgb, vec3(gamma));
特點:γ < 1:圖像變亮,主要拉昇暗部;γ > 1:圖像變暗,壓縮亮部。
具有兩個優點:
- 調整方式具有非線性特點,能更細膩地控制中間調亮度,避免簡單加法可能引起的局部過曝或暗部細節丟失。
- 模擬現實中顯示設備的響應曲線,效果較為自然。
這也是我們最後選擇的方式,他的運算量簡單,適合端上視頻播放的實時處理。
2.3.2 背後的原理
我們引申一下,這種方式的優點是怎麼得出來的呢。
- 為何能避免簡單加法可能引起的局部過曝或暗部細節丟失
從公式看,原本亮度較低的像素會被相對“提亮”更多,而原本亮度較高的像素提升幅度較小。暗部像素相對於原值會獲得更大的“提拉”,而亮部像素則變化較小,從而既能提升整體曝光,又能保留高光細節。
- 為什麼説模擬現實中顯示設備的響應曲線,更為自然呢?
因為顯示器、人眼視覺和視頻編碼,都是非線性系統,不是簡單線性變化。
- 真實世界的光亮度是線性的,比如兩支燈加起來就是兩倍亮。
- 但人眼感知亮度是對數感知的(小亮度變化很敏感,大亮度變化不敏感)。
- 視頻和圖像在存儲時通常經過一個 Gamma編碼,原本線性光 → 壓縮(比如取 1/2.2 次方) → 存成文件。這種光和電的轉換過程,就是OETF/EOTF響應曲線。
所以這種pow(color, gamma)的調整方式,實際就是在模擬顯示端的響應曲線。
總結一句話:
編碼有 Gamma,所以顯示端或後處理也必須按照 Gamma空間規則來調節,才能保持自然感知。
丨2.4 色彩增強
色彩增強效果示意圖(左:原圖 右:增強後)
從上圖可以看到山體、草地上的花,飽和度增強。
2.4.1 調節的目標
1. 增強色彩感知
提高圖像的“鮮豔度”或“視覺吸引力”,讓圖像更生動。
特別是在圖像顏色偏灰、曝光不佳或圖像壓縮後顏色損失的情況下。
2. 突出主體
通過飽和度調節,增強主體與背景之間的色彩對比,提高視覺聚焦度。
3. 修復/還原真實色彩
對攝像頭採集後色彩不足的圖像進行還原,尤其是膚色、植物、天空等自然色彩。
針對上述目標,我們主要依賴主觀評測感受,同時需要避免以下問題:
主觀評估(人眼視覺)
- 色彩鮮明但不刺眼:增強後色彩更加明顯但不過飽和。
- 膚色自然:人臉或皮膚色調不過紅或黃(膚色是視覺最敏感區域)。
- 色彩分佈均衡:圖像中顏色種類豐富但不過分集中某一色調。
- 無色彩斷層:調節後顏色過渡應平滑,不能有色階突變。
2.4.2 技術選型
目前業界對色彩增強主要有以下2種方向的研究:
- 傳統SDR色彩增強。
- SDR2HDR,模擬HDR效果,達到增強目的。
從實現方式上,主要也有2種主流方式:
1. 非神經網絡(傳統算法 or 結合lut查找表)
2. 基於神經網絡(模型)
模型需要較高的技術儲備,且在移動端運行耗時大,所以目前我們沒有選擇這種方式,而是尋找效果較好且可控的算法。
2.4.2.1 色彩三要素
我們先了解下“色彩三要素”。他們是色彩學中用於描述顏色感知的三個基本維度,分別是:色相、飽和度、明度。這三者共同定義了一個顏色的完整視覺特性。
色相
飽和度
明度
在色彩增強中,一般主要調節的是飽和度(Saturation),其次可能會適當調整明度(Brightness / Value) ,而色相(Hue)通常不會主動改變。原因如下:
常調節的要素及原因:
1. 飽和度(Saturation)
- 最常調節的要素,增強後畫面顯得更鮮豔、更有吸引力,尤其適用於風景、商品、動漫類畫面。可提升視覺衝擊力和色彩表現力。
- 明度 / 亮度(Brightness / Value)
- 有時作為輔助增強項,提高整體圖像的通透感。與 Gamma 調節、曝光補償常一起使用,即配合使用上一章節的亮度調整即可。
- 色相(Hue)
- 一般不調整,因為改變色相會改變物體本身顏色,可能導致不真實(如人臉偏色、草地變藍等)。只在需要藝術化或特殊濾鏡(如復古風格、紅外效果)時才會使用。
2.4.2.2 顏色空間的選擇
選擇好色彩增強的調節方向為『飽和度』後,第二步,我們需要選擇好顏色空間。
當視頻一幀畫面作為GL紋理輸入到後處理鏈路時,為RGB顏色模型,我們想要調節飽和度,則需要將其轉換為其他顏色空間進行調節,那麼面臨的第一個問題是如何選擇合適的顏色模型去進行算法設計?
- RGB
- HSV
- LCH/LAB
2.4.2.3 基於RGB空間
- 基於RGB顏色直接調節
們可以理解,飽和度是色彩的純度,即色彩相對於灰度(無色)的程度。那麼我們可以基於RGB顏色模型,並根據灰度進行差值混合即可。
如GPUImage的GPUImageSaturationFilter提供了類似例子,它對飽和度調節,是基於RGB顏色,然後取出灰度值通過在原始顏色和灰度之間插值,mix(vec3(luma), color.rgb, saturation) 實現了飽和度的變化:
- 插值因子 saturation 越接近 0,圖像越趨向於灰度;
- saturation 越高,圖像越接近原始顏色或超出原始飽和度,色彩更鮮豔。
這種簡單的算法存在一個問題:原本局部飽和度已經比較高,如果依然提高飽和度,則局部細節消失。
過飽和,細節丟失
2. 為了解決上述問題,我們基於自然飽和度的調整。
自然飽和度(Vibrance)的概念最先由photoshop提出,重點在於適應性,自然飽和度調整後一般比飽和度調整要自然。其核心特點:
進行自適應飽和度調節的流程:
- 計算亮度(Luma):使用加權平均公式從 RGB 獲取亮度:luma = 0.2126 r + 0.7152 g + 0.0722 * b
- 計算飽和度(Saturation):使用 RGB 最大值和最小值之差估算色彩純度:saturation = max(r, g, b) - min(r, g, b)
- 計算調節因子 k:根據當前飽和度和用户設置的 Vibrance 強度進行非線性調節:k = 1.0 + Vibrance * (1.0 - saturation / 255.0)(Vibrance 取值範圍通常為 0.0 ~ 1.0)
- 應用顏色調整:將顏色向亮度方向插值,使低飽和度顏色更鮮豔,同時高飽和區域變化較小:color.rgb = mix(vec3(luma), color.rgb, k)
其調整傾向於將RGB值往同一個luma值進行靠近,也是無法保證顏色保持穩定,容易會發生偏色的情況。
色彩增強效果示意圖(左:原圖 右:自然飽和度增強後)
於是,我們繼續探索其他的顏色模型。
2.4.2.4 基於HSV顏色模型的飽和度調整
基於HSV飽和度的調整方法是將RGB顏色模型轉換為HSV顏色模型,其中HSV分別表示色相(Hue)、飽和度(Saturation)、明度(Value)。只調整飽和度可以在不影響明暗和色相的情況下增強色彩的鮮豔程度。
將常見的調整方法有整體抬升,按比例增加,或者曲線調整,達到將整體飽和度提高的目的。但是飽和度調整同時提升所有顏色的強度,比較粗暴。
有可能導致:
- 本來局部飽和度已經比較高,調節後過飽和,局部細節的消失。(和上一章節例子一樣)。
- 本來局部飽和度較低,接近白色,加大飽和度後,容易出現色塊。
普通調節
如何優化:
- 對此引入對源的飽和度的檢測,設定上下限制,平滑調節。
- 在HSV顏色模型上,引入了類似自適應飽和度調整的方式。
- 目的:在低飽和度區域,避免突然增加飽和度。低飽和度的顏色(例如接近灰色的顏色)通常對飽和度調整非常敏感,因此需要一種平滑的方式。
- 目的:在高飽和度區域減少權重,避免過度增強飽和度。高飽和度的區域本身已經很飽和,進一步增加飽和度會導致過飽和,視覺上顯得不自然。
加入自適應後
2.4.2.5 膚色保護
採用HSV空間調整後,我們還需要考慮一個核心問題:
在圖像色彩增強(如飽和度調整、色調映射)時,膚色區域容易因過度調整而失真(如過紅、過黃或慘白)。需通過膚色識別技術,對檢測到的膚色區域進行保護,限制增強幅度,保持自然觀感。
在此引入了基於HSV色彩模型的膚色識別,HSV色彩模型也同樣將亮度與顏色進行了分離,因此對於光照變化也有很強的抗干擾能力,可以較好的識別出膚色。
結合HSV色彩模型和高斯概率模型實現膚色保護,具體步驟如下:參考GPUImageSkinToneFilter的膚色識別方法。
(1) RGB轉HSV空間
- 將圖像從RGB轉換到HSV空間,分離色調(H)、飽和度(S)、亮度(V)。
- 優勢:HSV的色調通道(H)對光照變化魯棒,更適合膚色識別。
(2) 膚色概率計算
-
膚色色調模型:
統計膚色色調的均值 skinHue = 0.05(典型值,對應黃紅色調)。
方差相關參數 skinHueThreshold = 40(控制膚色範圍寬度)。
-
距離計算:
計算當前像素色調 h 與 skinHue 的歸一化距離。
dist = abs(h - skinHue) / 0.5高斯權重(概率)。
-
通過高斯函數計算膚色概率:
skinProb = exp(-dist dist skinHueThreshold)結果範圍 [0, 1],越接近1表示越可能是膚色。
(3) 膚色區域保護
-
閾值分割:
設定閾值(如 skinProb > 0.95),二值化得到膚色掩膜(Mask)。
-
動態衰減增強強度:
對檢測到的膚色區域,按 skinProb 權重衰減色彩增強效果。例如:enhanced\_pixel = original\_pixel (1 - skinProb) + adjusted_pixel skinProb * alphaalpha 為衰減係數(如0.2),控制保護力度。
增加膚色保護後,可以看到效果明顯更好,人臉不會有過於突兀的顏色變化。
左:增強(無保護)中:原圖 右:增強(膚色保護)
2.4.3 效果對比
- HSV空間的調節後色彩更加自然。
- RGB空間調節則更加絢麗。但容易色偏。
- 基於綜合考慮,我們採用HSV空間調節,以適應更多的源,避免色偏。
三. 總結與展望
本研究聚焦於移動端視頻增強技術的工程化落地,重點驗證了亮度增強與色彩增強兩種核心算法的實際應用效果。從主觀評測效果看,在部分視頻上,兩項技術均能顯著提升視頻觀感質量,有效改善用户體驗。
目前,亮度增強功能已在「好看 App」成功上線,且收穫了良好的應用效果。現階段,我們正着力研發亮度增強與色彩增強相疊加的綜合優化方案,計劃通過這一方案對更多視頻內容進行品質升級,從而為用户帶來更優質的觀看體驗。以下為您呈現亮度增強結合色彩增強的部分應用案例:
例子1:後層次感更好(右)
例子2:色彩更鮮明(右)
例子3:畫面更清晰明亮(右)
未來研究將圍繞以下方向展開:
- 場景化優化:建立典型場景特徵庫,針對性優化算法參數配置。
- 實時性提升:通過模型輕量化與硬件加速技術,更加快速的視頻實時處理。