很多時候,我們需要對一個圖像的局部進行調整,這個調整必須是平滑的和可互動式的。Photoshop液化濾鏡中向前變形工具就是這樣一個工具,很好用。類似工具有美圖秀秀(http://xiuxiu.meit...
很多時候,我們需要對一個圖像的局部進行調整,這個調整必須是平滑的和可互動式的。Photoshop液化濾鏡中向前變形工具就是這樣一個工具,很好用。類似工具有美圖秀秀(http://xiuxiu.meitu.com/)的瘦臉功能。本文描述這類工具背後的原理與算法。
先以美圖秀秀為例子,簡單描述下向前變形功能。
首先,用滑鼠控制一個圓形的選區。
然後,點選滑鼠左鍵,向某個方向拖動,就可以産生光滑的向前變形圖檔:
通過這個工具,可對圖檔的局部進行調整,自由度比較大,是以比較實用。
下面講講這類算法的原理。
上圖中,陰影圓環代表一個半徑為 rmax 的圓形選區。其中,C點是滑鼠點下時的點,也就是圓形選區的圓心。滑鼠從C拖到M,緻使圖像中的點U變換到點X。是以,關鍵問題是找到上面這個變換的逆變換——給出點X時,可以求出它變換前的坐标U(精确的浮點坐标),然後用變化前圖像在U點附近的像素進行插值,求出U的像素值。如此對圓形選區内的每一個像素進行求值,便可得出變換後的圖像。
Andreas Gustafsson 的 Interactive Image Warping 一文給出了這一逆變換公式:
這個變形算法的特點是:
1 隻有圓形選區内的圖像才進行變形
2 越靠近圓心,變形越大,越靠近邊緣的變形越小,邊界處無變形
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=20:
變形,strength=120:
photoshop與美圖秀秀裡這個功能可以連續的進行變形。我猜測,這個連續的變形是由一系列基礎變形串聯起來的,也就是,滑鼠從M0拖到Mn位置,并不是隻計算M0->Mn這個變換,而是在滑鼠軌迹上引入一系列中間點,M1,M2…Mn-1,然後,對圖像進行M0->M1,M1->M2,…,Mn-1->Mn等一系列變換。
=================================================
最後,娛樂一下,來一個SB(蒼天哥,Sky Brother,簡稱"SB")最近的惡搞大作: