很多時候,我們需要對一個影像的局部進行調整,這個調整必須是平滑的、可互動的。 Photoshop液化濾鏡中向前變形工具就是這樣一個工具,很好用。類似工具有美圖秀秀的瘦臉功能。本文描述這類工具背後的原理與演算法。
先以美圖秀秀為例子,簡單描述下向前變形功能。
首先,用滑鼠控制一個圓形的選取範圍。
然後,點擊滑鼠左鍵,往某個方向拖曳,就可以產生光滑的向前變形圖片:
透過這個工具,可對圖片的局部進行調整,自由度比較大,因此比較實用。
下面講講這類演算法的原理。
上圖中,陰影圓環代表一個半徑為 rmax 的圓形選取範圍。其中,C點是滑鼠點下時的點,也就是圓形選區的圓心。滑鼠從C拖曳到M,致使影像中的點U變換到點X。所以,關鍵問題是找到上面這個變換的逆變換-給出點X時,可以求它變換前的座標U(精確的浮點座標),然後用變化前影像在U點附近的像素進行插值,求U的像素值。如此對圓形選取範圍內的每一個像素進行求值,便可得出變換後的影像。
Andreas Gustafsson 的Interactive Image Warping 一文給出了這個逆變換公式:
這個變形演算法的特點是:
1 只有越圓形選區內的圖像變形越大,越靠近邊緣的變形越小,邊界處無變形
3 變形是平滑的
具體實現步驟如下:
1 對於圓形選區裡的每一像素,取出其R,G,B各分量,存入3個Buff(rBuff, gBuff, bBuff)中(也即,三個Buff分別存儲選區內的原圖像的R,G,B三個通道的數值)
2 對於圓形選區裡的每一個像素X,
2.1 根據上面的公式,算出它變形前的位置座標精確值U
2.2 用插值方法,根據U的位置,和rBuff, gBuff, bBuff中的數值,計算U所在位置處的R,G,B等分量
2.3 將R,G,B等分量合成新的像素,作為X處的像素值
代碼我就不貼了,真正對這功能有需求的,根據上面的文字可以很容易寫出來——解決這類問題,重要的不是程式碼,而是想法和演算法。
下面是我的實作示範:
上圖中,左上角是原圖,右下角是變形後的圖。紅色圓圈圈起來的是變形區域。可以看見,變形很光滑。我在上面的演算法中引入了變形強度s(strength),上圖中strength=20。
引入strength,公式就得修改下,以下是我的修改版公式:
看結果-
原圖:
原圖: 🎜🎜變形,strength=120:
photoshop與美圖秀裡這個功能可以連續的進行變形。我猜測,這個連續的變形是由一系列基礎變形串聯起來的,也就是,滑鼠從M0拖到Mn位置,並不是只計算M0->Mn這個變換,而是在滑鼠軌跡上引入一系列中間點,M1,M2…Mn-1,然後,對影像進行M0->M1,M1->M2,…,Mn-1->Mn等一系列變換。
更多圖像變形演算法:實現Photoshop液化工具箱中向前變形工具相關文章請關注PHP中文網!