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實(shí)現(xiàn)yaml與json文件批量互轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了如何利用Python語(yǔ)言實(shí)現(xiàn)yaml與json文件的批量互轉(zhuǎn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動(dòng)手嘗試一下2022-07-07
深入分析python數(shù)據(jù)挖掘 Json結(jié)構(gòu)分析
這篇文章通過(guò)實(shí)例給大家分析總結(jié)了python數(shù)據(jù)挖掘以及Json結(jié)構(gòu)分析的相關(guān)知識(shí)點(diǎn),對(duì)此有興趣的朋友參考下。2018-04-04
pytorch使用tensorboard報(bào)錯(cuò)問(wèn)題及解決
這篇文章主要介紹了pytorch使用tensorboard報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Python實(shí)現(xiàn)比較兩個(gè)列表(list)范圍
這篇文章主要介紹了Python實(shí)現(xiàn)比較兩個(gè)列表(list)范圍,本文根據(jù)一道題目實(shí)現(xiàn)解決代碼,本文分別給出題目和解答源碼,需要的朋友可以參考下2015-06-06
利用Python代碼實(shí)現(xiàn)模擬動(dòng)態(tài)指針時(shí)鐘
這篇文章主要為大家詳細(xì)介紹了如何利用python和C++代碼實(shí)現(xiàn)模擬動(dòng)態(tài)指針時(shí)鐘,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-04-04
OpenCV實(shí)現(xiàn)去除背景識(shí)別的方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了如何利用OpenCV實(shí)現(xiàn)去除背景識(shí)別的功能,文中為大家總結(jié)了一些方法,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下2022-10-10

