深度学习AI美颜系列---美图秀秀AI美图之跨次元相机特效

news/2024/11/29 22:42:29/

深度学习AI美颜系列---美图秀秀AI美图之跨次元相机特效算法解析

最近在做类似美图秀秀AI美图里的跨次元相机特效算法,美图跨次元相机特效举例如下:

原图                                                                                          美图秀秀跨次元相机效果

Fig. 1美图秀秀跨次元相机特效举例

        跨次元相机特效是美图秀秀在2017年开发的一个全新的关于自拍的玩法,能够让自己的照片变成手绘美女,做到“照片一秒转手绘”,效果举例如上图所示。最初上线6种风格特效,分别为“天使之恋、十里桃花、童话萌主、樱之少女、人鱼眼泪、暗夜女爵”。

        美图秀秀跨次元相机特效是一个深度学习和传统算法相结合的算法组合,并非单一的深度学习算法或者传统算法可以实现的。

        这里本人将其划分为两个分析过程:表面分析、内在技术分析;

1,表面分析

①跨次元相机到目前为止,经历了快两年的时间,这么长的更新时间,目前来看,依旧火爆,而且市面上依旧没有其他类似效果的竞争对手;

②到目前为止,处理单张照片依旧耗时较长,一般在2-3s左右;

③这项功能对照片上传大小有较强要求,需要用户上传图像大小不能小于某一尺寸,同时,需要正脸半身照片,五官无遮挡;

上述三点可以看出美图该算法复杂度较高,不易优化,或者无法实时处理,更无法应用到相机界面,同时,无法较好的处理小脸非半身照片case;

2,内在技术分析

从Fig.1的效果对比来看,本人对其总结如下几点:

①人像照片做了背景替换,使用到了人像分割技术;

②人像区域中,仅仅头发区域进行了头发丝特效处理和头发区域特效处理,该过程比较复杂,据官方声明,使用到了机器学习或者DL技术判断头发纹理走势,在纹理走势下绘制发丝效果,目前具体技术尚不可知;

③人像美妆,在图中可以看到,眉毛、眼影、瞳孔和唇彩等都发生了变化,因此,使用了人像美妆技术;

④人像美颜,在图中对比可以发现,效果图中眼睛变大,人脸变小,五官立体感增强,因此,该算法使用了大眼瘦脸、立体五官等脸部微调技术;

⑤人像整体画面的亮度对比度发生了明显的变化,因此,个人猜测,该算法具有自动亮度对比度调节功能;

⑥原图和效果图中,人像表面增加了特有的贴纸效果,因此,该算法使用了静态贴纸技术;

⑦头发丝绘制算法,美图跨次元中的头发丝绘制效果,可谓时转手绘的点睛之笔;

       基于上述猜测,本人对应实现该算法,效果举例如下:

原图                                                                                     本人跨次元相机算法效果

Fig.2 本人算法效果

        在本人算法中没有使用静态贴纸,这个可以随意添加,整体上实现了类似的效果,但是头发丝绘制部分还没有美图秀秀的梦幻,没有它更接近手绘风格;

        整体而言,这个特效算法允许用户自定义背景,前景贴纸,头发丝绘制颜色以及面部妆容和人脸变形等内容,但由于算法的复杂度,仅仅适合服务器端运行,可以实现对应微信小程序或H5调用,目前本人算法耗时在1S以下,略优于美图秀秀。

        关于算法的具体实现,本文不做详细展示,所用到的算法及代码链接如下:

         ①人脸自动美型      人脸变形

         ②人像染发

         ③人像美颜之磨皮美白   磨皮美白2

         ④人像抠图

         ⑤人像美妆     妆容迁移

         ⑥颜色滤镜

         ⑦头发柔顺

          关于头发柔顺方面,本人博客中之前并未介绍过,这里给出一个参考链接,该链接来自大佬Imageshop:           https://www.cnblogs.com/Imageshop/p/10797177.html

         使用的时LIC线积分算法来处理头发区域的,线积分的示意图如下:

Fig.3 LIC算法示意图

        代码如下:

///        make white noise as the LIC input texture     ///
void MakeWhiteNoise(int  Width, int  Height, unsigned char*  pNoise)
{srand(100000);for (int j = 0; j < Height; j++)for (int X = 0; X < Width; X++){int  r = rand();r = ((r & 0xff) + ((r & 0xff00) >> 8)) & 0xff;pNoise[j * Width + X] = (unsigned char)r;}
}
//LIC
void FastFlowImagingLIC_Appr(int  Width, int  Height, float*  pVectr, unsigned char*  pNoise, unsigned char*  pImage, float   krnlen)2 {3     float Step = 0.333333f;                                    //    每次前进0.33333像素的流线距离                                        4     int LoopAmount = int(krnlen / Step);            //    流线是左右对称的5     if (LoopAmount <= 0)    LoopAmount = 1;6     int Weight = LoopAmount * 2;7     for (int Y = 0; Y < Height; Y++)8     {9         unsigned char *LinePD = pImage + Y * Width;
10         float *LinePV = pVectr + Y * Width * 2;
11         for (int X = 0; X < Width; X++, LinePV += 2)
12         {
13             float PosX_P = X + 0.5f, PosY_P = Y + 0.5f, PosX_N = X + 0.5f, PosY_N = Y + 0.5f;
14             float VectorX = LinePV[0] * 0.333333f, VectorY = LinePV[1] * 0.333333f;
15             int Sum = 0;
16             for (int Z = 0; Z < LoopAmount; Z++)
17             {
18                 PosX_P += VectorX;    PosY_P += VectorY;            //    X和Y都是归一化的,所以*0.333333f后流线距离也就是0.25了
19                 PosX_N -= VectorX;    PosY_N -= VectorY;
20                 int Index_P = IM_ClampI(PosY_P, 0, Height - 1) * Width + IM_ClampI(PosX_P, 0, Width - 1);
21                 int Index_N = IM_ClampI(PosY_N, 0, Height - 1) * Width + IM_ClampI(PosX_N, 0, Width - 1);
22                 Sum += pNoise[Index_P] + pNoise[Index_N];
23             }
24             LinePD[X] = (unsigned char)(Sum / Weight);
25         }
26     }
27 }

        在Imageshop的链接中有详细的讲解,对应效果如图所示:

 Fig.4 线积分特效效果举例  

        上述就是整个算法过程的分析,在实际开发中,这个特效综合了十余种复杂的算法技术,囊括了美颜美妆以及图像分割等等内容,算法知识上需要大家对各个方面都有全面的认识,介于商业信息问题,本文仅作技术上的分析,不做详细代码展示,掌握了算法之后,相信大家代码不是问题!

        这里感谢Imageshop大佬的分享!

          

        

 

 

 


http://www.ppmy.cn/news/661085.html

相关文章

java入门之 美图相机(原图、灰度、二值化、马赛克、融合、轮廓获取)

编写美图相机时&#xff0c;我们首先需要了解图片再计算机中的存储形式&#xff0c;详情可见http://t.csdn.cn/MgOfO 目录 <1>创建显示图片的主界面 1.添加窗体&#xff0c;用数列添加按钮&#xff0c;设置窗体可视化&#xff0c;添加主函数 2.先创建对象&#xff0c;…

使用cat EOF命令插入变量

有的时候在容器内修改配置文件比较麻烦&#xff0c;没有vi命令无法编辑文件 记录一下在没有vi的情况下常用的命令 例1&#xff1a; 往nginx服务配置文件追加配置&#xff0c;$host是变量的形式&#xff0c;只需要把第一个EOF加引号即不会被转义 cat << EOF >> d…

二层交换机有IP地址吗?

二层交换机本身不具有IP地址。它工作在数据链路层,主要进行MAC地址学习与转发。 但是,二层交换机上会存在一些有IP地址的网络设备,主要包括: 管理接口:二层交换机上会有一个用于管理交换机的接口,通常连接交换机的Console口或AUX口,该接口配置有IP地址,用于通过网络管理交换机…

《九》TypeScript 中的内置工具

TypeScript 内置了很多类型工具&#xff0c;来辅助进行类型转换。 Partial<Type>&#xff1a; Partial<Type>&#xff1a;用于构造一个所有属性都为可选属性的类型。 interface IPerson {name: stringage: number }// personOptional 类型的所有属性都是可选的 …

这几天系统总是在慢慢地推几天前写的问答

这几天系统总是在慢慢地推几天前写的问答&#xff0c;一天给个几万展现&#xff0c;就怕给多了浪费了。 难道是前几天给得太多&#xff0c;没人读&#xff0c;头条发现了&#xff0c;所以才一点点给&#xff1f; 已经好久没有爆款的感觉了[捂脸] 其实也不怪头条不给流量&#x…

慢慢开始创作吧

认真学习java技术的第一天&#xff0c;贵在坚持&#xff0c;一步一步来吧。

好好生活 慢慢期待

我从未真正忘记过你&#xff0c;你永远是我青春序列里最勇敢的篇章。