抖音快手 APP"大眼特效"开源实现,换了一个甜美系小姐姐做效果演示 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
exmorning
V2EX    程序员

抖音快手 APP"大眼特效"开源实现,换了一个甜美系小姐姐做效果演示

  •  
  •   exmorning 2020-07-29 08:40:52 +08:00 12197 次点击
    这是一个创建于 1979 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大眼特效

    抖音短视频中的大眼特效有很多人玩,这篇就讲一下怎么实现。本文为《抖音美颜效果开源实现,从 AI 到美颜全流程讲解》姐妹篇,很多代码和内容都类似,看过的同学可以直接看效果和源码。

    demo1

    下图为演示小姐姐

    demo1

    大眼特效原理

    大眼特效原理的美颜差不多,都是 AI 和计算机图形学的结合

    美颜是的基本原理就是深度学习加计算机图形学。深度学习用来人脸检测和人脸关键点检测。计算机图形学用来磨皮,瘦脸和画妆容。一般在 Android 上使用 OpenGLES,IOS 为 Metal 。

    来源抖音美颜效果开源实现,从 AI 到美颜全流程讲解

    人脸检测 & 人脸关键点

    1. 人脸检测指的是对图片或者视频流中的人脸进行检测,并定位到图片中的人脸。
    2. 人脸关键点检测是对人脸中五官和脸的轮廓进行关键点定位,一般情况下它紧接在人脸检测后。

    face landmarks

    我们将使用 TengineKit 来实现大眼特效。

    TengineKit

    免费移动端实时人脸 212 关键点 SDK 。是一个易于集成的人脸检测和人脸关键点 SDK 。它可以在各种手机上以非常低的延迟运行。
    https://github.com/OAID/TengineKit

    TengineKit 效果图

    demo1

    实现大眼特效

    配置 Gradle

    Project 中的 build.gradle 添加

     repositories { ... mavenCentral() ... } allprojects { repositories { ... mavenCentral() ... } } 

    主 Module 中的 build.gradle 添加

     dependencies { ... implementation 'com.tengine.android:tenginekit:1.0.5' ... } 

    配置 manifests

     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 

    处理 Gif 传过来的图片流

    首先我们先初始化 TengineKit:

    1. 选用 normal 处理模式
    2. 打开人脸检测和人脸关键点功能
    3. 设置图片流格式为 RGBA
    4. 设置输入图片流的宽高,此处为 gif 图的预览宽高
    5. 设置输出图片流的宽高,此处为 GifImageView 的宽高,此处和 gif 一致,所以用 gif 图的宽高代替
     com.tenginekit.Face.init(getBaseContext(), AndroidConfig.create() .setNormalMode() .openFunc(AndroidConfig.Func.Detect) .openFunc(AndroidConfig.Func.Landmark) .setInputImageFormat(AndroidConfig.ImageFormat.RGBA) .setInputImageSize(facingGif.getGifWidth(), facingGif.getGifHeight()) .setOutputImageSize(facingGif.getGifWidth(), facingGif.getGifHeight()) ); 

    通过关键点得眼睛的中心点

     Point getLeftEyeCenter(FaceLandmarkInfo fi){ FaceLandmarkPoint p1 = fi.landmarks.get(105); FaceLandmarkPoint p2 = fi.landmarks.get(113); return new Point((int)((p1.X + p2.X) / 2), (int)((p1.Y + p2.Y) / 2)); } Point getRightEyeCenter(FaceLandmarkInfo fi){ FaceLandmarkPoint p1 = fi.landmarks.get(121); FaceLandmarkPoint p2 = fi.landmarks.get(129); return new Point((int)((p1.X + p2.X) / 2), (int)((p1.Y + p2.Y) / 2)); } 

    眼睛放大算法

    public class MagnifyEyeUtils { /** * 眼睛放大算法 * @param bitmap 原来的 bitmap * @param centerPoint 放大中心点 * @param radius 放大半径 * @param sizeLevel 放大力度 [0,4] * @return 放大眼睛后的图片 */ public static Bitmap magnifyEye(Bitmap bitmap, Point centerPoint, int radius, float sizeLevel) { Bitmap dstBitmap = bitmap.copy(Bitmap.Config.RGB_565, true); int left = centerPoint.x - radius < 0 ? 0 : centerPoint.x - radius; int top = centerPoint.y - radius < 0 ? 0 : centerPoint.y - radius; int right = centerPoint.x + radius > bitmap.getWidth() ? bitmap.getWidth() - 1 : centerPoint.x + radius; int bottom = centerPoint.y + radius > bitmap.getHeight() ? bitmap.getHeight() - 1 : centerPoint.y + radius; int powRadius = radius * radius; int offsetX, offsetY, powDistance, powOffsetX, powOffsetY; int disX, disY; //当为负数时,为缩小 float strength = (5 + sizeLevel * 2) / 10; for (int i = top; i <= bottom; i++) { offsetY = i - centerPoint.y; for (int j = left; j <= right; j++) { offsetX = j - centerPoint.x; powOffsetX = offsetX * offsetX; powOffsetY = offsetY * offsetY; powDistance = powOffsetX + powOffsetY; if (powDistance <= powRadius) { double distance = Math.sqrt(powDistance); double sinA = offsetX / distance; double cosA = offsetY / distance; double scaleFactor = distance / radius - 1; scaleFactor = (1 - scaleFactor * scaleFactor * (distance / radius) * strength); distance = distance * scaleFactor; disY = (int) (distance * cosA + centerPoint.y + 0.5); disY = checkY(disY, bitmap); disX = (int) (distance * sinA + centerPoint.x + 0.5); disX = checkX(disX, bitmap); //中心点不做处理 if (!(j == centerPoint.x && i == centerPoint.y)) { dstBitmap.setPixel(j, i, bitmap.getPixel(disX, disY)); //dstBitmap.setPixel(j, i, Color.WHITE); } } } } return dstBitmap; } private static int checkY(int disY, Bitmap bitmap) { if (disY < 0) { disY = 0; } else if (disY >= bitmap.getHeight()) { disY = bitmap.getHeight() - 1; } return disY; } private static int checkX(int disX, Bitmap bitmap) { if (disX < 0) { disX = 0; } else if (disX >= bitmap.getWidth()) { disX = bitmap.getWidth() - 1; } return disX; } } 

    此代码来源于 https://github.com/DingProg/Makeup

    渲染

    传过来的 bitmap 为 RGB_565,需要转为标准的 RGBA 格式

     facingGif.setOnFrameAvailable(new GifImageView.OnFrameAvailable() { @Override public Bitmap onFrameAvailable(Bitmap bitmap) { // bitmap RGB_565 Bitmap out_bitmap = Bitmap.createBitmap( facingGif.getGifWidth(), facingGif.getGifHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(out_bitmap); canvas.drawBitmap(bitmap, 0, 0, null); bitmap.recycle(); byte[] bytes = bitmap2Bytes(out_bitmap); Face.FaceDetect faceDetect = com.tenginekit.Face.detect(bytes); if(faceDetect.getFaceCount() > 0){ faceLandmarks = faceDetect.landmark2d(); if(faceLandmarks != null){ for (int i = 0; i < faceLandmarks.size(); i++) { FaceLandmarkInfo fi = faceLandmarks.get(i); out_bitmap = MagnifyEyeUtils.magnifyEye(out_bitap, getLeftEyeCenter(fi), 40, 4); out_bitmap = MagnifyEyeUtils.magnifyEye(out_bitmap, getRightEyeCenter(fi), 40, 4); } } } return out_bitmap; } }); 

    效果对比

    demo demo

    建议

    有兴趣的同学可以在当前项目的基础上面深化,具体可以参考
    https://github.com/DingProg/Makeup

    参考

    1. TengineKit - Free, Fast, Easy, Real-Time FaceDetection & FaceLandmark SDK on Mobile.

    2. Makeup - 让你的“女神”逆袭,代码撸彩妆(画妆)

    3. CainCamera - CainCamera is an Android Project to learn about development of beauty camera, image and short video

    源码

    https://github.com/jiangzhongbo/TengineKit_Demo_Big_Eyes

    知乎

    https://zhuanlan.zhihu.com/p/164803269

    V2EX 系列

    推荐一个 Github 上面免费用的 Android 人脸关键点 SDK,Demo 图中的小姐姐好漂亮

    尝试 AI 人脸关键点算法实现一下 Android 人脸匿名功能

    抖音美颜效果开源实现,从 AI 到美颜全流程讲解

    40 条回复    2020-08-06 09:25:07 +08:00
    leimao
        1
    leimao  
       2020-07-29 08:43:48 +08:00 via iPhone   3
    我绝对不会为网红花一分钱
    nksky
        2
    nksky  
       2020-07-29 08:57:42 +08:00   1
    第一张图我看着有点恐怖
    littiefish
        3
    littiefish  
       2020-07-29 08:59:28 +08:00 via iPhone   4
    畸形审美
    40EaE5uJO3Xt1VVa
        4
    40EaE5uJO3Xt1VVa  
       2020-07-29 08:59:33 +08:00
    眼睛大的像 ET 了
    mugglezzz
        5
    mugglezzz  
       2020-07-29 09:18:15 +08:00
    @nksky #2 第一张图是 阿丽塔 啦
    takemeaway
        6
    takemeaway  
       2020-07-29 09:24:36 +08:00
    我比较好奇 TengineKit 是全自己研发的算法吗?
    还是挺厉害的
    usVexMownCzar
        7
    usVexMownCzar  
       2020-07-29 09:28:59 +08:00
    太想 ET 了
    exmorning
        8
    exmorning  
    OP
       2020-07-29 09:31:16 +08:00
    @takemeaway 是啊,从端侧推理引擎到算法都是自己搞的
    mmrx
        9
    mmrx  
       2020-07-29 09:31:51 +08:00
    哈哈哈哈大眼动图可太恐怖了

    感谢楼主分享
    exmorning
        10
    exmorning  
    OP
       2020-07-29 09:33:07 +08:00
    @mmrx 特地做大了点,为了展示效果
    xrr2016
        11
    xrr2016  
       2020-07-29 09:41:29 +08:00
    话说战斗天使啥时候出第二部啊?第一部才讲了漫画的一点内容...
    Soar360
        12
    Soar360  
       2020-07-29 09:43:19 +08:00
    死鱼眼的既视感
    nguoidiqua
        13
    nguoidiqua  
       2020-07-29 09:51:15 +08:00   3
    假脸时代。

    对于国内各种自拍、网上的美照什么的已经完全无了,美颜太过了,经常挡一下脸就会看到脸忽然变大一圈大,然后马上又变小了,感觉很无语。
    revalue
        14
    revalue  
       2020-07-29 09:58:49 +08:00
    哪有人把眼袋放大得那么大啊,混蛋
    ln1225707801
        15
    ln1225707801  
       2020-07-29 10:10:18 +08:00 via Android
    效果蛮厉害的,就是审美需要加强
    zhangchongjie
        16
    zhangchongjie  
       2020-07-29 10:12:22 +08:00 via Android
    opencv 可以做到吗
    wushigejiajia01
        17
    wushigejiajia01  
       2020-07-29 10:13:24 +08:00
    @xrr2016 你参考下阿凡达, 反正没看到片子, 卡梅隆这人是不能信了
    exmorning
        18
    exmorning  
    OP
       2020-07-29 10:39:33 +08:00
    @zhangchongjie 可以的,就是 opencv 性能在 mobile 侧不行
    UnitTest
        19
    UnitTest  
       2020-07-29 10:44:28 +08:00
    感谢技术分享,学习了。
    就是效果有点 creepy 。。
    exmorning
        20
    exmorning  
    OP
       2020-07-29 11:06:10 +08:00
    @UnitTest 为了效果牺牲了颜值~
    buliugu
        21
    buliugu  
       2020-07-29 13:04:24 +08:00
    有点恐怖谷效应
    zhangchongjie
        22
    zhangchongjie  
       2020-07-29 13:15:24 +08:00 via Android
    @exmorning 嗯嗯,没试过,做 web 的看看热闹
    exmorning
        23
    exmorning  
    OP
       2020-07-29 13:22:20 +08:00
    @zhangchongjie 有时间,我用 nodejs 包一下
    takemeaway
        24
    takemeaway  
       2020-07-29 13:53:28 +08:00
    看起来像 ERT 算法,其实还是做得不错的。 看识别率了
    qwertyiuop
        25
    qwertyiuop  
       2020-07-29 13:55:22 +08:00
    用 shader 和人脸蒙版会更好
    exmorning
        26
    exmorning  
    OP
       2020-07-29 13:56:30 +08:00
    @takemeaway 暴力上 MobileNet
    exmorning
        27
    exmorning  
    OP
       2020-07-29 13:57:44 +08:00
    @stnaw 这样就是不是入门级的文章了,上 canvas 为了让初学者能快速玩起来
    root8080
        28
    root8080  
       2020-07-29 14:41:54 +08:00
    小姐姐快秃了 注意保养
    exmorning
        29
    exmorning  
    OP
       2020-07-29 16:47:09 +08:00
    @root8080 我会转告的
    IzayakI
        30
    IzayakI  
       2020-07-30 05:52:17 +08:00
    第一张图是铳梦里的阿丽塔吧,漫画好看,电影故事讲得稀烂。


    还有,后面的对比 gif,这个大眼好看嘛?莫名其妙的。
    exmorning
        31
    exmorning  
    OP
       2020-07-30 12:04:12 +08:00
    @IzayakI 为了看出效果,特地做大了些
    LZSZ
        32
    LZSZ  
       2020-07-30 17:29:47 +08:00
    有点像青蛙 原谅我这么说
    vinew
        33
    vinew  
       2020-07-30 17:30:43 +08:00
    小姐姐可能还需要植发特效,发量渐少了
    GM
        34
    GM  
       2020-07-30 17:36:50 +08:00
    一行源码都没有,我是不是理解错“开源”的意思了?
    Rh1
        35
    Rh1  
       2020-08-01 00:12:23 +08:00 via iPhone
    真是什么玩意都可以扯到“国内”“国外”.... 滤镜美颜这种东西在全球都很火好吗?
    GG668v26Fd55CP5W
        36
    GG668v26Fd55CP5W  
       2020-08-01 00:25:41 +08:00 via iPhone
    太吓人了我去
    erek
        37
    erek  
       2020-08-01 18:48:42 +08:00
    期待阿丽塔第二部
    CoderGeek
        38
    CoderGeek  
       2020-08-04 10:03:49 +08:00
    666
    djs
        39
    djs  
       2020-08-04 18:55:43 +08:00
    吓死我了。。。那个大眼图
    minglanyu
        40
    minglanyu  
       2020-08-06 09:25:07 +08:00
    这小姐姐... 这大眼...
    我欣赏不了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5810 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 02:07 PVG 10:07 LAX 18:07 JFK 21:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86