今天將主要介紹基於GPUImage實現美顏濾鏡的原理和思路。圖玩智能科技爲企業提供更穩定更優質的美顏產品及服務,歡迎諮詢www.toivan.comgit
GPUImage
GPUImage 是一個開源的基於GPU的圖片或視頻的處理框架,其自己內置了多達120多種常見的濾鏡效果。有了它,添加實時的濾鏡只須要簡單地添加幾行代碼。下面的例子是以攝像頭的數據爲源,對其實時地進行反色的操做(相似相片底片的效果):github
利用GPUImage對攝像頭數據添加濾鏡的示例2.1算法
其實美顏也是同樣,若是有這麼一個美顏的濾鏡(姑且叫作GPUImageBeautifyFilter),那麼只須要把示例2.1中的GPUImageColorInvertFilter替換成GPUImageBeautifyFilter便可。咱們只須要作一個GPUImageBeautifyFilter就能實現實時美顏了,問題來了,到底什麼算是美顏呢?個人理解是,你們對於美顏比較常見的需求就是磨皮、美白。固然提升飽和度、提亮之類的就根據需求而定。本文將着重介紹磨皮的實現(實際上GPUImageBeautifyFilter也實現了美白、提亮等效果)。框架
磨皮函數
磨皮的本質其實是模糊。而在圖像處理領域,模糊就是將像素點的取值與周邊的像素點取值相關聯。而咱們常見的高斯模糊 ,它的像素點取值則是由周邊像素點求加權平均所得,而權重係數則是像素間的距離的高斯函數,大體關係是距離越小、權重係數越大。下圖3.1是高斯模糊效果的示例:工具
高斯模糊效果示例3.1spa
若是單單使用高斯模糊來磨皮,獲得的效果是不盡人意的。緣由在於,高斯模糊只考慮了像素間的距離關係,沒有考慮到像素值自己之間的差別。舉個例子來說,頭髮與人臉分界處(顏色差別很大,黑色與人皮膚的顏色),若是採用高斯模糊則這個邊緣也會模糊掉,這顯然不是咱們但願看到的。而雙邊濾波(Bilateral Filter) 則考慮到了顏色的差別,它的像素點取值也是周邊像素點的加權平均,並且權重也是高斯函數。不一樣的是,這個權重不只與像素間距離有關,還與像素值自己的差別有關,具體講是,像素值差別越小,權重越大,也是這個特性讓它具備了保持邊緣的特性,所以它是一個很好的磨皮工具。下圖3.2是雙邊濾波的效果示例:視頻
雙邊濾波效果示例3.2blog
對比3.1和3.2,雙邊濾波效果確實在人臉細節部分保留得更好,所以我採用了雙邊濾波做爲磨皮的基礎算法。雙邊濾波在GPUImage中也有實現,是GPUImageBilateralFilter。圖片
根據圖3.2,能夠看到圖中仍有部分人臉的細節保護得不夠,還有咱們並不但願將人的頭髮也模糊掉(咱們只須要對皮膚進行處理)。由此延伸出來的改進思路是結合雙邊濾波,邊緣檢測以及膚色檢測。總體邏輯以下:
磨皮處理邏輯圖3.3
Combination Filter是咱們本身定義的三輸入的濾波器。三個輸入分別是原圖像A(x, y),雙邊濾波後的圖像B(x, y),邊緣圖像C(x, y)。其中A,B,C能夠當作是圖像矩陣,(x,y)能夠當作其中某一像素的座標。Combination Filter的處理邏輯以下圖:
Combination Filter邏輯圖3.3
下面是主要的shader代碼:
combination filter的shader代碼3.4
Combination Filter經過膚色檢測和邊緣檢測,只對皮膚和非邊緣部分進行處理。下面是採用這種方式進行磨皮以後的效果圖:
最終磨皮效果圖3.5
對比3.5與3.2,能夠看到3.5對人臉細節的保護更好,同時對於面部磨皮效果也很好,給人感受更加真實。