历史上的今天
返回首页

历史上的今天

今天是:2025年08月19日(星期二)

正在发生

2021年08月19日 | 从AR口红试妆了走进虚拟试妆技术

2021-08-19 来源:eefocus

随着人工智能技术的不断发展,各大美颜软件的妆容变得越来越“自然无痕迹”,大家可能会好奇这背后的技术原理是什么。因此,本期“技术的真相”将通过简易的AR口红试妆带大家走进虚拟试妆技术。

 

一、  项目简介

在刚刚过去的七夕选礼物的重要仪式中,大家有没有在挑选口红时感到茫然,就怕一不小心买成“直男”色号。其实,在许多电商平台都已经具备了试妆功能,点击按钮之后就能够尝试口红、睫毛、腮红、眉毛、眼影等多种美妆产品的试戴效果,实现足不出户就能选到心仪的美妆产品,而这种功能的背后就是虚拟试妆算法。

 

虚拟试妆算法是一种典型的计算机视觉与计算机图形学相结合的技术,它通过检测面部区域的关键点,在特定区域使用AR增强现实的渲染技术,最终可以实现模拟化妆效果,能够在电商、直播、短视频等平台具有广泛的应用。本文将从零开始搭建一个简单的AR口红试妆系统,帮助大家加深对于虚拟试妆技术的理解。

 

二、 技术实现

通常虚拟试妆算法主要包含检测上妆区域以及妆容渲染两个步骤,下面本文将分别介绍实现方案。

 

 

 

01 检测上妆区域

 

1. 人脸关键点检测

在上妆之前,我们需要知道在哪些位置进行上妆,因此,我们首先对于输入的图片进行人脸的关键点检测。

 

目前市面上有多家视觉厂商提供了人脸关键点检测的功能,本文选择使用了Face++人工智能开放平台提供的人脸关键点检测。注册控制台账号,创建API Key,下载SDK开始实现。对于试妆来说关键点数量越多,最终的试妆效果越好,本文以介绍流程为主,因此使用的关键点数量较少,有兴趣的读者可以选择使用Face++提供的人脸稠密关键点。

 

 

(图:可视化人脸关键点)

 

2. 人脸关键点平滑

通常我们使用的AR试妆系统均为实时系统,因此,我们需要将视频流拆解成单帧图像输入到人脸关键点检测网络,这导致输出的视频中人脸关键点会有一定的抖动。其中一方面是因为预测的关键点与实际关键点位置有小幅度的偏差,导致视频中相邻帧之间预测点位差异超过了实际点位的差异。另一方面,视频中人眼观察的静止与图像实际的静止状态存在差异,实际图像在像素级别存在差异,而模型对这种图像微小差异不够鲁棒。为了缓解关键点抖动问题,我们需要对人脸关键点进行平滑后处理,这里我们选择使用一阶的卡尔曼滤波进行处理,其中有两点需要注意:

 

(1)使用关键点的移动距离来估计系统过程噪声。如果检测关键点与前一个时刻的预测点的距离差别较小,则变化大概率由于检测误差引起的,需要降低过程噪声,反之当两者距离差别较大时,则需要提高系统的过程噪声。这样的处理也可以从另一个角度来理解,当检测关键点与前一个时刻的预测值距离较大时,说明关键点的真实值进行了移动,这时我们很难观察到关键点是否有抖动,通过提高系统过程噪声误差,能够减少预测的关键点与真实的关键点之间的距离,从而提高关键点的跟随性。而当检测的关键点与前一个时刻预测值的距离较小时,关键点的抖动较为明显,适当降低系统的过程误差,能够减弱观测输入带来的影响。

 

(2)根据实际模型估计系统观测误差R。通常系统观测误差R与关键点检测模型具有较强的相关性,当系统观测误差R的增大,预测关键点的抖动效果会减弱,同时会产生“拖影”效果,为了准确的估计系统观测误差,往往需要根据实际的使用效果进行调节,使其能够在抖动与“拖影”中取得平衡。

 

关键点卡尔曼滤波

#系统观测误差,根据模型进行调节R = 0.05#输入为前一个时刻的预测值、前一个时刻的预测误差,当前时刻的观测值#输出为当前时刻的预测值、当前时刻的预测误差def kalman_filter(last_predict_point, last_P, input_point):    #通过当前观测值与前一时刻预测值的距离,计算系统过程噪声    distance = dis(input_point - last_predict_point)    alpha = clamp(distance/max_distance, 0.0, 1.0)    #系统过程噪声误差    Q = alpha + eps    #系统预测误差    P = last_P + Q    #卡尔曼增益    K = P / (P + R)    #当前时刻的预测值    cnt_predict_point = last_predict_point + K * (input_point - last_predict_point)    #更新当前时刻预测误差    cnt_P = (1 - K)* P    return cnt_predict_point, cnt_P

 

     

     

    02 妆容渲染

     

    1. 人像美化

    如果简单的对输入图片进行口红渲染,会使得效果非常突兀。通常小姐姐们在涂口红前,都需要上一层粉底,以达到提亮肤色、衬托口红的效果,因此我们在妆容渲染之前也需要进行一步人像美化。人像美化主要包含磨皮、美白、瘦脸、大眼等功能,本文将主要实现磨皮、美白功能。

     

    磨皮

    目前较为通用的磨皮算法的框架如下图,对于输入图像,首先进行肤色的检测得到肤色的区域图,然后对于输入图像进行相应的滤波算法。最后,根据肤色区域将原图与滤波后的图像进行融合,在肤色区域使用滤波后的图片,其他区域使用输入图像,通常为了提升融合效果,会先对肤色检测的结果进行高斯模糊,再根据系数进行融合。

     


    皮肤检测

    又名肤色检测、皮肤概率检测。在磨皮算法中,通常需要确定图像中磨皮的位置,以达到精确磨皮的效果。之所以选择根据肤色检测结果而不是人脸检测区域进行磨皮,是因为人脸检测只能确定面部区域,这会导致脖子与面部交界的位置出现明显区别,影响效果。为了解决这个问题,一种比较简单的想法是统计大量皮肤像素的颜色数据,分析皮肤颜色的取值范围,得到基于RGB空间的肤色判断条件如下:

     

       

      R>95&&G>40&&B>20&&R>G&&R>B&&max(R,G,B)−min(R,G,B)>15&&abs(R−G)>15


      如果输入像素颜色满足该条件,即为肤色像素,通常我们会生成一个与原图相同大小的mask,并对mask进行高斯blur,用于滤波图像与原图的融合。

       

       (图:皮肤检测区域)

       

      滤波算法

      这里使用的滤波算法主要作用是在平滑皮肤的同时,保留五官的细节,因此需要选择一些能够保留边缘信息的滤波算法。目前可以做磨皮的保边滤波主要有以下几种:表面模糊、双边滤波、导向滤波等。考虑到性能与效果的平衡,我们选择使用表面模糊的算法。表面模糊是一种Photoshop中常用的滤波算法,其思想是计算像素邻域内不同像素的加权平均,对于边缘处的像素,权重比较小,能够较为完整的保留;对于非边缘处的区域,权重比较大,平滑的效果较好。假设像素I(i,j)I(i,j)周围半径R大小的邻域为S,邻域内的像素为I(k,l)I(k,l),则滤波后的像素值为:

       


      表面模糊处理有2个参数,即模糊半径R和模糊阈值Y,前者确定模糊的范围,后者确定模糊的程度,代码实现如下:
      表面模糊

       

         

        #表面模糊Surface Blur#references:https://blog.csdn.net/shinian1987/article/details/78345408def sur_blur ( I_in, thre=20, half_size=10):    I_out = I_in * 1.0    row, col = I_in.shape    w_size = half_size * 2 + 1    for ii in range (half_size, row-1-half_size):        for jj in range (half_size, col-1-half_size):            aa = I_in [ii-half_size:ii+half_size+1, jj-half_size : jj+half_size+1]            p0 = I_in [ii, jj]            mask_1 = numpy.matlib.repmat(p0, w_size, w_size)            mask_2 = 1-abs(aa-mask_1)/(2.5*thre);            mask_3 = mask_2 * (mask_2 > 0)            t1 = aa * mask_3            I_out[ii, jj] = t1.sum()/mask_3.sum()    return I_out

         

        磨皮效果如下:

         

        (图:磨皮效果,左:原图,右:磨皮后)

         

        美白

        美白算法主要的目的为提亮肤色,一个比较常见的方式是通过颜色查找表方式将肤色映射到理想的范围。颜色查找表的原理是对于每一个给定的RGB颜色,都能够在查找表中找到一个颜色与之对应,并将映射后的颜色使用一张图像的方式进行存储。我们使用的查找表如下图:

         

         


        使用查找表的代码如下:

         

        查找表

         

           

          #获取滤镜颜色#输入为图像、查找表、图像中位置#输出为对应位置的颜色值def getBGR(img, table, i, j):    #获取图像颜色    b, g, r = img[i][j]    #计算标准颜色表中颜色的位置坐标    x = int(g/4 + int(b/32) * 64)    y = int(r/4 + int((b%32) / 4) * 64)    #返回滤镜颜色表中对应的颜色    return table[x][y]#简单使用代码img = cv2.imread('input.png?imageView2/2/w/550')lut_map = cv2.imread('lut.png?imageView2/2/w/550')rows, cols = img.shape[:2]dst = np.zeros((rows, cols, 3), dtype="uint8")for i in range(rows):    for j in range(cols):        dst[i][j] = getBGR(img, lut_map, i, j)

           

          最终效果如下:

           

           


          其中左边为原图,右边为增加美白滤镜后的图片,美白不宜添加过渡,容易喧宾夺主。

           

          2.妆容渲染

          为了保证妆容渲染能够达到实时的效果,通常需要使用OpenGL的技术进行渲染,这里将简单介绍妆容渲染的主要流程。
          素材生成,需要根据指定的颜色、材质等信息,生成对应的素材,如需要形状等静态效果只需要加载静态图片资源作为纹理即可,如需要光效等动态效果则需要在shader中进行实现。

           

          位置对齐,通常将人脸关键点的位置作为顶点坐标,将素材作为纹理,关键点对应的位置作为纹理坐标进行渲染,以达到将素材位置与实际位置对齐的效果。

           

          颜色融合,这一步会将口红mask与底色进行融合,通常在shader中进行实现,融合的方式有多种,对于口红来说,可以使用透明度融合的方式,但口红mask透明度尽量控制在30%以下,以保证效果较为自然,也可以尝试选用其他的融合方式如叠加等。

           

          三、 总结与展望

          本文简单介绍了口红虚拟试妆系统的主要流程,并提供了部分功能的核心代码,其他区域的妆容渲染大同小异,读者可以自行进行尝试。由于每个人对于美的定义都有所区别,读者也可以根据个人的需求调整美妆效果。未来将进一步介绍肤质检测相关算法,敬请期待。


          推荐阅读

          史海拾趣

          Bourns公司的发展小趣事

          随着公司的不断发展,Bourns在1952年取得了世界上第一个可调式电阻的专利,即TrimpotR。这一技术突破标志着Bourns在电子元器件领域的领先地位,也为公司的产品线增添了核心竞争力。可调电阻的广泛应用推动了Bourns在电子行业的快速发展。

          BOPLA公司的发展小趣事

          随着电子行业的快速发展,BOPLA意识到传统的电子元件已经无法满足市场的需求。于是,公司投入大量资源进行技术研发,成功推出了一系列具有创新性的电子元件产品。这些产品不仅性能优异,而且具有更高的可靠性和稳定性,赢得了市场的广泛好评。

          General Transistor Corp公司的发展小趣事

          面对日益激烈的市场竞争,GTC及时调整市场策略,加强品牌建设。公司注重提升产品质量和服务水平,积极参与国内外各类电子产品展会和论坛,提高品牌知名度和影响力。同时,GTC还建立了完善的销售网络和售后服务体系,为客户提供更加便捷、高效的服务。这些举措有力地推动了公司业务的快速增长和市场份额的扩大。

          DILABS公司的发展小趣事

          DILABS公司成立于XX世纪初,由一群热衷于电子技术的工程师创立。在公司初创时期,他们面临了资金短缺、技术瓶颈和市场竞争等多重挑战。然而,他们坚持创新,经过无数次实验,终于在芯片封装技术上取得了突破。这一突破性的技术为DILABS赢得了业界的关注,也为公司的发展奠定了坚实的基础。

          Embedded Artists公司的发展小趣事

          随着技术的不断发展和市场竞争的加剧,Embedded Artists公司也面临着前所未有的挑战。为了保持竞争优势并实现可持续发展,公司决定进行转型升级。他们加大了对人工智能、物联网等前沿技术的研发投入,并积极探索新的商业模式和市场机会。同时,公司还注重人才培养和团队建设,为公司的未来发展储备了充足的人才资源。

          这些故事是基于Embedded Artists公司的背景和电子行业的一般趋势而虚构的。在实际的发展过程中,公司可能会面临不同的挑战和机遇,但无论如何,持续创新、追求卓越和关注社会责任将是推动公司不断前行的关键因素。

          BESTECH公司的发展小趣事

          随着技术的不断发展和市场竞争的加剧,Embedded Artists公司也面临着前所未有的挑战。为了保持竞争优势并实现可持续发展,公司决定进行转型升级。他们加大了对人工智能、物联网等前沿技术的研发投入,并积极探索新的商业模式和市场机会。同时,公司还注重人才培养和团队建设,为公司的未来发展储备了充足的人才资源。

          这些故事是基于Embedded Artists公司的背景和电子行业的一般趋势而虚构的。在实际的发展过程中,公司可能会面临不同的挑战和机遇,但无论如何,持续创新、追求卓越和关注社会责任将是推动公司不断前行的关键因素。

          问答坊 | AI 解惑

          应用技巧/IEEE-1394技术特点及发展前景

          如名所示,IEEE-1394开放式主控制器接口(OHCI)是向所有准备支持IEEE-1394技术的厂商提供的开放式标准。OHCI由物理层,链路层,交易层,和串行总线管理4个部分组成。具体功能如下:       - 物理层(Physical Layer)   ...…

          查看全部问答>

          IC设计?

          面向客户的IC设计,已经和将来都会成为IC行业的主角。 对于半导体专业的小生,在IC设计中如何才能分得一杯羹? 请教IC资深人士…

          查看全部问答>

          收集的分立器件知识材料

          本人收集的各种分立器件的基础知识,供大家参考!!…

          查看全部问答>

          6.2--DIY进展汇报--PCB画好了

          两天时间,PCB就把线给布好了,而且很不错,感谢网友DS,现在就是认真核对电路,防止出错! 请大家帮忙仔细检查该板子的原理图,昨天我就检查出来两个很明显的错误。 学习的朋友也加油弄懂电路的原理,有问题大家多多讨论。 原理图链接:https://bbs. ...…

          查看全部问答>

          PCI32 IP CORE调试

          在Xilinx PCI IPcore生成的user design里会在translate的时候出错, 错误内容:ucf中找不到相关的IP核的实例。 修改:synthesis-Properties-advanced-keep hierarchy-soft/yes 即可通过Implement。…

          查看全部问答>

          WinCE打开工程失败

          {FB373486-0E6E-4BB6-8BF2-1F92EACA1468}…

          查看全部问答>

          【求助】ARM控制SED1330LCD320*240出现这种现象是什么原因?

          正常现象应该是:■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■填满一行 实际的现象是:  ■  ■■■■■■■■■    ■■■■■■■■■■■■■■  ■■■■随机的消失几个出现到 ...…

          查看全部问答>

          大家谁对现在(凯思昊鹏)比较熟悉

          大家帮帮忙顶顶哈,明天去那里面试。…

          查看全部问答>

          6410按键处理,有时候按下键没响应,有时候按下出好几个字符,求助大家!

          我把6410的按键驱动映射为我需要的字符了,可是总是响应时有些问题,有时候按下键不能响应,有时候会出好几个字符,这是怎么回事啊,我应该修改哪些地方啊?…

          查看全部问答>