pytorch?液態(tài)算法實(shí)現(xiàn)瘦臉效果
論文:Interactive Image Warping(1993年Andreas Gustafsson)
算法思路:

假設(shè)當(dāng)前點(diǎn)為(x,y),手動(dòng)指定變形區(qū)域的中心點(diǎn)為C(cx,cy),變形區(qū)域半徑為r,手動(dòng)調(diào)整變形終點(diǎn)(從中心點(diǎn)到某個(gè)位置M)為M(mx,my),變形程度為strength,當(dāng)前點(diǎn)對(duì)應(yīng)變形后的目標(biāo)位置為U。變形規(guī)律如下,
- 圓內(nèi)所有像素均沿著變形向量的方向發(fā)生偏移
- 距離圓心越近,變形程度越大
- 距離圓周越近,變形程度越小,當(dāng)像素點(diǎn)位于圓周時(shí),該像素不變形
- 圓外像素不發(fā)生偏移

其中,x是圓內(nèi)任意一點(diǎn)坐標(biāo),c是圓心點(diǎn),rmax為圓心半徑,m為調(diào)整變形的終點(diǎn),u為圓內(nèi)任意一點(diǎn)x對(duì)應(yīng)的變形后的位置。
對(duì)上面公式進(jìn)行改進(jìn),加入變形程度控制變量strength,改進(jìn)后瘦臉公式如下,

優(yōu)缺點(diǎn):
優(yōu)點(diǎn):形變思路簡(jiǎn)單直接
缺點(diǎn):
- 局部變形算法,只能基于一個(gè)中心點(diǎn),向另外一個(gè)點(diǎn)的方向啦。如果想多個(gè)點(diǎn)一起拉伸,只能每個(gè)點(diǎn)分別做一次液化,通過(guò)針對(duì)多個(gè)部位多次液化來(lái)實(shí)現(xiàn)。
- 單點(diǎn)拉伸的變形,可以實(shí)現(xiàn)瘦臉的效果,但是效果自然度有待提升。
代碼實(shí)現(xiàn):
import cv2
import math
import numpy as np
def localTranslationWarpFastWithStrength(srcImg, startX, startY, endX, endY, radius, strength):
ddradius = float(radius * radius)
copyImg = np.zeros(srcImg.shape, np.uint8)
copyImg = srcImg.copy()
maskImg = np.zeros(srcImg.shape[:2], np.uint8)
cv2.circle(maskImg, (startX, startY), math.ceil(radius), (255, 255, 255), -1)
K0 = 100/strength
# 計(jì)算公式中的|m-c|^2
ddmc_x = (endX - startX) * (endX - startX)
ddmc_y = (endY - startY) * (endY - startY)
H, W, C = srcImg.shape
mapX = np.vstack([np.arange(W).astype(np.float32).reshape(1, -1)] * H)
mapY = np.hstack([np.arange(H).astype(np.float32).reshape(-1, 1)] * W)
distance_x = (mapX - startX) * (mapX - startX)
distance_y = (mapY - startY) * (mapY - startY)
distance = distance_x + distance_y
K1 = np.sqrt(distance)
ratio_x = (ddradius - distance_x) / (ddradius - distance_x + K0 * ddmc_x)
ratio_y = (ddradius - distance_y) / (ddradius - distance_y + K0 * ddmc_y)
ratio_x = ratio_x * ratio_x
ratio_y = ratio_y * ratio_y
UX = mapX - ratio_x * (endX - startX) * (1 - K1/radius)
UY = mapY - ratio_y * (endY - startY) * (1 - K1/radius)
np.copyto(UX, mapX, where=maskImg == 0)
np.copyto(UY, mapY, where=maskImg == 0)
UX = UX.astype(np.float32)
UY = UY.astype(np.float32)
copyImg = cv2.remap(srcImg, UX, UY, interpolation=cv2.INTER_LINEAR)
return copyImg
image = cv2.imread("./tests/images/klst.jpeg")
processed_image = image.copy()
startX_left, startY_left, endX_left, endY_left = 101, 266, 192, 233
startX_right, startY_right, endX_right, endY_right = 287, 275, 192, 233
radius = 45
strength = 100
# 瘦左邊臉
processed_image = localTranslationWarpFastWithStrength(processed_image, startX_left, startY_left, endX_left, endY_left, radius, strength)
# 瘦右邊臉
processed_image = localTranslationWarpFastWithStrength(processed_image, startX_right, startY_right, endX_right, endY_right, radius, strength)
cv2.imwrite("thin.jpg", processed_image)實(shí)驗(yàn)效果:

到此這篇關(guān)于pytorch 液態(tài)算法實(shí)現(xiàn)瘦臉效果的文章就介紹到這了,更多相關(guān)pytorch 液態(tài)算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 19個(gè)值得學(xué)習(xí)的編程技巧
這篇文章主要介紹了python 19個(gè)值得學(xué)習(xí)的編程技巧,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下2020-08-08
關(guān)于Python的pymouse click 雙擊的問(wèn)題
這篇文章主要介紹了關(guān)于Python的pymouse click 雙擊的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
Python greenlet實(shí)現(xiàn)原理和使用示例
這篇文章主要介紹了Python greenlet實(shí)現(xiàn)原理和使用示例,greenlet是Python中的一個(gè)并行處理庫(kù),需要的朋友可以參考下2014-09-09
Python使用正則表達(dá)式分割字符串的實(shí)現(xiàn)方法
今天小編就為大家分享一篇Python使用正則表達(dá)式分割字符串的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07

