资讯专栏INFORMATION COLUMN

瘦脸之液化算法

BWrong / 2291人阅读

摘要:对上面公式进行改进,加入变形程度控制变量,改进后瘦脸公式如下,优缺点优点形变思路简单直接缺点局部变形算法,只能基于一个中心点,向另外一个点的方向啦。单点拉伸的变形,可以实现瘦脸的效果,但是效果自然度有待提升。

论文:Interactive Image Warping(1993年Andreas Gustafsson)

算法思路

假设当前点为(x,y),手动指定变形区域的中心点为C(cx,cy),变形区域半径为r,手动调整变形终点(从中心点到某个位置M)为M(mx,my),变形程度为strength,当前点对应变形后的目标位置为U。变形规律如下,

  1. 圆内所有像素均沿着变形向量的方向发生偏移
  2. 距离圆心越近,变形程度越大
  3. 距离圆周越近,变形程度越小,当像素点位于圆周时,该像素不变形
  4. 圆外像素不发生偏移

其中,x是圆内任意一点坐标,c是圆心点,rmax为圆心半径,m为调整变形的终点,u为圆内任意一点x对应的变形后的位置。

对上面公式进行改进,加入变形程度控制变量strength,改进后瘦脸公式如下,

优缺点

优点:形变思路简单直接

缺点:

  1. 局部变形算法,只能基于一个中心点,向另外一个点的方向啦。如果想多个点一起拉伸,只能每个点分别做一次液化,通过针对多个部位多次液化来实现。
  2. 单点拉伸的变形,可以实现瘦脸的效果,但是效果自然度有待提升。

代码实现

import cv2import mathimport numpy as npdef 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    # 计算公式中的|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 copyImgimage = cv2.imread("./tests/images/klst.jpeg")processed_image = image.copy()startX_left, startY_left, endX_left, endY_left = 101, 266, 192, 233startX_right, startY_right, endX_right, endY_right = 287, 275, 192, 233radius = 45strength = 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)

实验效果

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/125087.html

相关文章

  • 天然气专题研究报告(合集)

    摘要:查看行业专题分析报告就上参一江湖,更多专题报告持续更新中。 查看行业专题分析报告就上参一江湖,更多专题报告持续更新中。每项专题报告都是从2019开始更新到至今,后续将持续更新... 今天为大家分享天然气专题研究报告的部分目录如下 : ———————公众号:参一江湖———————  2021...

    Tamic 评论0 收藏0
  • 小记-用canvas完成图像液化(向前变形)过程

    摘要:前几天由于团队需要,折腾了一下图像液化的处理过程。现在来整理一下思路,做个记录。用到公式如下,网上拿来的话不多说,上代码本来想尽量写出点逼格。。。后来发现怎么写也还是几个搞定,就那样了。然后再用的把转换后的输出到中效果图如下 前几天由于团队需要,折腾了一下图像液化的处理过程。 现在来整理一下思路,做个记录。 用到公式如下,网上拿来的 showImg(https://segm...

    Cheng_Gang 评论0 收藏0
  • 小记-用canvas完成图像液化(向前变形)过程

    摘要:前几天由于团队需要,折腾了一下图像液化的处理过程。现在来整理一下思路,做个记录。用到公式如下,网上拿来的话不多说,上代码本来想尽量写出点逼格。。。后来发现怎么写也还是几个搞定,就那样了。然后再用的把转换后的输出到中效果图如下 前几天由于团队需要,折腾了一下图像液化的处理过程。 现在来整理一下思路,做个记录。 用到公式如下,网上拿来的 showImg(https://segm...

    jone5679 评论0 收藏0
  • 最少知识原则模式的黄金原则

    摘要:最少知识原则的终极目标的是实现完全傻瓜式的程序。我们如何做到解除对象间的耦合性主要手段还是很多的。最少知识原则的实现其实,最少知识原则和单一原则所达到目的是相似的,一个是,让你的程序对外尽量简单,一个是让你的程序里的对象,相互联系尽量简单。 最少知识原则的终极目标的是实现完全傻瓜式的程序。 举个例子吧, 就比如 美图神器, 你上传一张凤姐的照片后,你可以选择 自然磨皮,高度磨皮 -> ...

    Ocean 评论0 收藏0

发表评论

0条评论

BWrong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<