具有膚質保留功能的磨皮演算法及其實現細節

2021-07-04 09:41:47 字數 4034 閱讀 4107

**:

在幾年前寫的一篇關於beep的文章時,我曾經說過beep的去噪作用可以用於磨皮,並且給出了結論beep比可牛和美圖等的效果要更為好,現在看來,那個結論確實是太為誇張和固定了。不同的人的審美觀不同,同乙個人在不同時段審美觀也會有所差異,現在看來,我到時覺得可牛影像的帶有膚質保留效果的磨皮更加自然,也更加符合實際的情況。

2、用外掛程式磨皮

這一步很重要,直接影響最終效果,磨光一些,不要擔心紋理。

平湖老師可能用的neatimage,我這裡使用的是portraiture, 把紅框內的滑塊都拉到最大。

當時自己沒有neatimage,也未安裝portraiture,所以對這個教程就不以為然了。

當我再次瀏覽此教程時,終於耐下心自己試驗了下, 雖然我還是沒有安裝neatimage和portraiture,但是可以直接用ps自帶的表面模糊來替代,雖然效果會有所不同,但是卻不影響演算法的核心效果。事實再次證明乙個真理:別人講一千遍好,不如自己都一次感受深。

那麼這個教程的乙個最關鍵的效果就是磨皮的同時保留了膚質,很類似於可牛影像的效果,而多次的實踐證明,可牛軟體100%也是採用了類似的過程。

我們把那個教程的簡單操作步驟列表如下:

1、複製乙個圖層,我們定義改層名字為highpass

2、用外掛程式對highpass層磨皮;

3、應用影象,模式選擇減去,縮放值為1,偏差128;

4、更改highpass層混合模式為線性光,不透明度合適取值。

5、對highpass層進行高斯模糊,模糊半徑0.5-2左右。

基本就這樣收工了,似乎沒有什麼高深複雜的東西。

至於效果:我們用幾幅實際的影象來測試下(第二步用表面模糊來代替)。

去斑需要的紋理圖 

結果圖(表面模糊引數半徑=10,閾值=16)

原圖

去斑需要的紋理圖 

結果圖(表面模糊引數半徑=10,閾值=50)

為了程式的實現,我們對每個步驟都進行對應的分析,為方便,我們假定原始影象層為src層。

(1)複製圖層: 這個沒啥好說的,無非是分配乙個同樣大小的記憶體,然後memcpy 函式複製 src到highpass層。

highpass= copy(src);

(2)對highpass層磨皮:這個演算法可以選擇:表面模糊、導向濾波、雙邊濾波、各向異性擴散、beep、區域性均方差、domain transfer、 adaptive manifolds、 local laplacian filters等任何具有保邊效果的epf-filter,這裡不多說。

表示式為:  highpass = epf-filter(highpass);

(3)應用影象:這裡的介面看上去似乎很複雜,那**是不是很複雜呢,其實**簡單的嚇人,就是下面的計算公式:

hihgpass = highpass - src + 128;

看上去這個公式是不是很熟悉,不錯,這個和高反差保留的演算法是一模一樣的,只是photoshop內嵌的高反差保留用的是高斯模糊,這裡用的是epf濾波器而已。

(4) 從程式設計角度來說,要把上述過程的第四步和第五步調換順序,否則會得到錯誤的結果,因此這裡第四步是:

highpass = guassblur(highpass, radius);

其中radius為高斯模糊的半徑。

(5) 進行圖層混合: 線性光混合的計算公式也很簡單:

假定兩個相鄰圖層x和y,x在下方,y在上方,x與y混合,則x是基色,y是混合色,x與y混合得到的顏色是結果色z,對於線性光混合模式,其計算公式為:

z = x + 2 * y - 256;    (原先以為是  - 255,後用ps cs6驗證是 - 256)

不透明度的計算公式就更為簡單,如果opacity表示y的不透明度,則合成公式為:

z = (x * (100- opacity) + y * opacity ) / 100;

那麼兩個綜合在一起的計算公式為:

z =  (x * (100- opacity) + (x + 2 * y - 256)* opacity ) / 100;

綜合上述五個步驟,最後的計算公式即為:

dest =(src * (100 - opacity) + (src + 2 * guassblur(epffilter(src) - src + 128) - 256) * opacity) /100 ;

總的來說,這個演算法並沒有什麼特別複雜的地方,其關鍵的恢復**質感的步驟是第四步的高斯模糊,這個模糊的半徑一般越大,質感越強,但是太大,磨皮效果就沒有了,因此,這裡需要把握合適的度,一般半徑在0.5-2之間比較合適。

至於為什麼用了這個高斯模糊就可以恢復影象的質感,我其實也是有些想法的,不過目前還不成熟,暫時不管他,知道結果而不管緣由有的時候也是一種幸福。 

再如第三步應用影象中常數128,其實也不一定是個定值,如果把他調大,則處理後的影象整體偏亮,調小則影象偏暗。

第五步的圖層的不透明度引數也是乙個道理,如果不透明度值越大,則整體的斑點可能會偏多,偏小,那麼影象又會過於模糊,也許取個50%是個不錯的選擇吧,或者自己根據處理的紋理圖的某個指標做個演算法更好吧。

演算法速度方面其實主要取決於第二步,也就是epf濾波器,這個就是個各顯神通的好地方,不多言。

其次就是高斯模糊的計算,高斯模糊必然有浮點計算,這對於手機等其他硬體,可能是個硬傷。而如果用方框模糊或者線性模糊等代替,則存在乙個問題就是模糊的最小幅度即半徑為1時,紋理恢復的效果都有點過,特別是在我的程式中,高斯模糊的計算用了差不多佔了整個用時的1/3.

如果看下這個的流程,可以認為美圖里的任何乙個磨皮演算法都只是進行了該流程的第二步就為止了,如果他在加上後續的處理,也一定能有和可牛類似的效果。

最後鄙視下可牛和美圖程式的磨皮演算法的速度吧(我指的是pc上程式的速度):

我用的基於區域性均方差的磨皮方式外加銳化等過程的耗時針對上面第二幅所謂的美女平均耗時約 35ms(基於表面模糊),25ms(基於均方差);

而可牛或者美圖我估計感覺了,至少要有1000ms左右。

那麼類似的ps教程比如這裡: 的一下幾個過程演算法其實也很簡單,並且也有著相當不錯的效果,而如果從實現上考慮也就只要一下幾個過程:

invert(src, dest);

highpass(dest, dest,

10);

guassblur(dest, dest, 1);

blendimage(src, dest, dest, blendmode::overlay,

255);

最後我們來比較下可牛、美圖、本文的處理效果:

美圖秀秀的智慧型模糊 程度深

可牛的磨皮 力度5 

本文的磨皮效果

可以看出,本文的效果和可牛的非常接近,可以說明可牛也採用的該演算法。

附上乙個按照所謂平湖法的流程的做的乙個測試程式:   仿可牛磨皮特效.rar

一種具有細節保留功能的磨皮演算法。

話說女人的錢最好賺,所以現在各大流行的影象編輯小軟體基本上都有個磨皮的功能,這對那些臉上不小心長了小痘痘或者小斑點的美眉來說是在上傳 前的必要和必須步驟。加上現在自戀的人特多,沒事有事來個 然後掛到網上炫一把,當然也得把自己的 處理好。因此啊,國內出了不少這方面的軟體,比如美圖 可牛 美顏相機 美人...

具有提示功能的KeyPath巨集

巨集的定義 define keypath obj,keypath void obj.keypath,keypath 示例 import viewcontroller.h define keypath obj,keypath void obj.keypath,keypath implementatio...

MFC 具有提示功能的工具欄

在文件 檢視結構的應用程式中,預設情況下,當滑鼠在工具欄按鈕上停留片刻,會出現乙個工具提示條。那麼在基於對話方塊的應用程式中能夠實現該功能嗎?執行本案例,將滑鼠移至工具欄上的某一按鈕上,即可看到該工具按鈕的提示資訊,效果如下圖所示。系統環境 windows 10 開發環境 visual studio...