文档章节

肤色检测算法 - 基于二次多项式混合模型的肤色检测。

abcijkxyz
 abcijkxyz
发布于 2016/11/22 16:38
字数 1540
阅读 8
收藏 0
点赞 0
评论 0

   由于能力有限,算法层面的东西自己去创新的很少,很多都是从现有的论文中学习,然后实践的。

      本文涉及的很多算法,在网络上也有不少同类型的文章,但是肯定的一点就是,很多都是不配代码的,或者所附带的代码都是象征性的,速度慢,不优雅,不具有实用价值,本文努力解决这些问题。

      文中各算法出现的顺序并不代表算法的优越性,仅仅是作者随机排布的而已。

      1、二次多项式混合模型

           二次多项式混合模型首先有SORIANO提出,此后CHIANG对此进行了改进。改进后的模型由两个R-G平面的二次多项式和一个圆方程构成:

      

  在以上三个方程的基础上,肤色区域可以通过一下规则实现:

               

     上述算法的参考论文:Adaptive skin color modeling using the skin locus.pdf  

            A novel method for detecting lips,eyes and faces in real time

  以及百度文库相关文章:基于混合肤色模型的快速人脸检测算法 

     上式中,小写r,g,b(未涉及)为对R/G/B(byte类型的数据,0-255)进行归一化后的数据,即:

             

     如上所示,算法中涉及到了不少的浮点运算,以及大量的乘法,如果按照源汁原味的来编写代码,程序的效率可想而知。因此,我们着手于算法的优化。

     首先,我们来看四个判断条件,由于判断条件是不分先后,需要同时满足的地方才是区域,因此应该把简单的判断条件放在最前面判断。

     首先看如果符合了判断条件R4,条件R3中的R>G肯定是已经成立的,则只需要判断G是否大于B,这是优化手段1。   

     然后我们来看R2的优化,为方便表达,我们这里令Sum=R+G+B,将判断条件R2展开:

                     

     上式子最后一步同时乘以156, 理论上说156×0.33=51.48,不应该取52的,不过这个0.33本来就是个经验数据,谁说不能是1/3呢。

     到此,我们看到在式子的最右侧还有个浮点数0.0624,如果不消除该数据,算法速度依旧会有大的影响,常常研究移位的朋友肯定对0.0625这个数字很熟悉,1/16=0.0625,不是吗,懂了吗,还不懂,看代码吧(这里的式子很多都是经验公式,因此,稍微修改一些参数对结果基本无影响)。

     上述这样做的目的,无非是将浮点数的运算全部转换为整数的运算。

  最后来看式R1的优化,R1实际上也是两个条件,把他分开来,分别称为R11及R12,对于R11,同样展开:

               

     现在大部分的PC都还是32位的系统,因此,使用32位的整数类数据类型速度是最快的,因此,如果上述放大系数的取夺就必须主要使得计算式两边的值都在int.MinValue和 int.MaxValue之间,比如上式,>号左侧算式的肯能最大取值为10000×255×765,是小于int.MaxValue所能表达的范围的,因此放大系数是合理的。

     对于R12的展开我想应该不需要我在去贴出来了吧。

     算法部分参考代码:

for (Y = 0; Y < Height; Y++)
{
    Pointer = Scan0 + Y * Stride;
    SkinP = SkinScan0 + Y * SkinStride;
    for (X = 0; X < Width; X++)
    {
        *SkinP = 0;                                 // 非皮肤区域为黑色

Blue
= *Pointer; Green = *(Pointer + 1); Red = *(Pointer + 2); if (Red - Green >= 45) // 符合条件R4 { if (Green > Blue) // 符合条件R3 { Sum = Red + Green + Blue; T1 = 156 * Red - 52 * Sum; T2 = 156 * Green - 52 * Sum; if (T1 * T1 + T2 * T2 >= (Sum * Sum) >> 4) // 符合条件R2,在32位系统要尽量避免用long类型数据, { T1 = 10000 * Green * Sum; Lower = - 7760 * Red * Red + 5601 * Red * Sum + 1766 * Sum * Sum; // 把这里的公用的乘法提取出来基本没啥优化的效果 if (T1 > Lower) // 符合条件R11 { Upper = - 13767 * Red * Red + 10743 * Red * Sum + 1452 * Sum * Sum ; if (T1 < Upper) // 符合条件R12 { *SkinP = 255;      } } } } } Pointer += 3; SkinP++; }

  本人特喜欢优化,特别是代码层面的优化,比如上述的 Lower = 5601 * Red * Sum + 1766 * Sum * Sum 这句,偶尔我写成Lower =- Red * Red * 7760+ 5601 * Red * Sum + 1766 * Sum * Sum 这样,然后没事的时候我反汇编了两种写法有什么不同,结果如下:

Lower =-7760 * Red * Red+ 5601 * Red * Sum + 1766 * Sum * Sum ;         // 把这里的公用的乘法提取出来基本没啥优化的效果
00000118  imul        ebx,ecx,0FFFFE1B0h 
0000011e  imul        ebx,ecx 
00000121  imul        eax,ecx,15E1h 
00000127  imul        eax,esi 
0000012a  add         ebx,eax 
0000012c  imul        eax,esi,6E6h 
00000132  imul        eax,esi 
00000135  add         ebx,eax

 

Lower = -Red * Red * 7760 * +5601 * Red * Sum + 1766 * Sum * Sum;         // 把这里的公用的乘法提取出来基本没啥优化的效果
00000118  mov         ebx,ecx 
0000011a  neg         ebx 
0000011c  imul        ebx,ecx 
0000011f  imul        ebx,ebx,1E50h 
00000125  imul        ebx,ebx,15E1h 
0000012b  imul        ebx,ecx 
0000012e  imul        ebx,esi 
00000131  imul        eax,esi,6E6h 
00000137  imul        eax,esi 
0000013a  add         ebx,eax

     可见多了两条汇编语句的。可能这个优化举在这里不合适,因为有个系数-7760,一般谁都不会像上面写,但是如果系数是-1,那就比一定了,比如如果是-Red+Blue 和Blue-Red那就有着截然不同的意义了。

      这个算法的皮肤检测效果还是很不错的,那原文中的图像来举例如下:

            

             原图                                                           梦版图                                                      合成图

 然后贴一张别人博客上的照片的例子(一群帅哥和美女):

 检测结果:

   由于是有选择性的执行,因此程序执行的速度其实和图像的内容有关,同样一副大小的图像,如果皮肤部分站的比例越大,执行的时间可能就会越长,就上述这幅800*600的图像来说,在我I3的笔记本上仅用了4ms就得到了结果,因此速度是相当的快的。

     

 

***************************作者: laviewpbt   时间: 2013.8.17   联系QQ:  33184777  转载请保留本行信息*************************

 

 

 

 

本文转载自:http://www.cnblogs.com/Imageshop/p/3264238.html

共有 人打赏支持
abcijkxyz
粉丝 61
博文 6195
码字总数 1876
作品 0
深圳
项目经理
Win8 Metro(C#)数字图像处理--2.35图像肤色检测算法

原文:Win8 Metro(C#)数字图像处理--2.35图像肤色检测算法  [函数名称] 肤色检测函数SkinDetectProcess(WriteableBitmap src) [算法说明] 这个算法是一篇学术论文算法的实现,论文名字为“...

杰克.陈 ⋅ 03/13 ⋅ 0

基于 OpenCV 的裸体检测

AI(人工智能)被用来处理一些奇怪的任务。算法网站Algorithmia搞出了一个“裸体检测器”,当然这不是能通过图灵测试的超级AI,也不是《终结者》中“天网”级别的机器人。 据称,原理如下:首...

oschina ⋅ 2015/06/30 ⋅ 21

自己做的一个肤色检测模型

肤色检测 在人像美化中,肤色检测有助于防止磨掉头发、胡子等需要保持细节的部分,也可以使美白算法仅作用于皮肤,不对人像周边环境产生影响。 网上找了一下肤色检测模型,效果都太差,换了一...

jxt1234 ⋅ 2015/10/15 ⋅ 0

广州颜鉴信息科技--即将亮相移动美妆开发包

1引言 古人曰,女为悦己者容。在化妆技术日益成熟的今天,化妆的目的已经不仅于此,社会的文明程度越高,化妆就越显示出其必要性。化妆是人们为了适应实用,场合、环境、 礼仪和特定的情景需...

colorreco ⋅ 2016/09/29 ⋅ 0

深度学习AI美颜系列---天天P图疯狂变脸算法

自从天天P图出了疯狂变脸的特效之后,到现在为止已经近两年时间了,这两年时间,天天P图多次凭借换脸特效登上APP Store排行榜首,从小学生证件照到圣诞节梦幻妆再到后来的各种影视游戏特效,...

trent1985 ⋅ 05/13 ⋅ 0

广州颜鉴人脸识别

广州颜鉴信息科技有限公司是一家拥有自主知识产权的科技创新公司,专注于人脸识别技术的研发与技术支持服务,致力于打造新一代的计算机视觉理解和人工智能引擎,让计算机以及其他智能硬件能看...

colorreco ⋅ 2016/08/30 ⋅ 0

肤色检测有个地方报错了

@老崔No1 你好,想跟你请教个问题:Android的肤色检测,149行R.drawable.bg报错了 求解啊!

xiaoxiao999 ⋅ 2013/12/19 ⋅ 0

Android实现基于肤色的皮肤检测

在android上实现 基于肤色的皮肤检测的几个技术要点: (1)android上使用相机预览,包括相机api的使用和surfaceview的应用。 (2)android上相机使用的色彩空间NV12. (3)NV12是YCrCb的色彩空...

老崔No1 ⋅ 2013/04/22 ⋅ 7

阿里云CDN图片鉴黄服务正式上线,人工智能助力企业降低违规风险

摘要: 随着直播、视频、图片等内容形态的爆发与各大移动社交媒体、UGC平台的兴起,内容安全问题也逐渐凸显。每天海量的用户图片、视频,夹杂其中的淫秽色情等内容让平台方措手不及,传统鉴黄...

姬子玉 ⋅ 2017/12/06 ⋅ 0

Java版色情图像过滤入门示例及源码-0.1.0 (模拟GreenDam过滤机制)

文件下载地址(源码在jar中):http://code.google.com/p/greenvm/downloads/list 这些天来,笔者对于[绿坝]的赞美犹如滔滔江水连绵不绝,又似黄河决口,一发不可收拾。 “心之所慕,情之所仰...

cping ⋅ 2009/06/28 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

收集自网络的wordpress 分页导航的代码教程(全网最全版)

wordpress 分页导航是用来切换文章的一个功能,添加了 wordpress 分页导航后,用户即可自由到达指定的页面数浏览分类文章,而这样的一个很简单功能却有很多朋友在用插件:WP-PageNavi,插件的...

Rhymo-Wu ⋅ 24分钟前 ⋅ 0

微服务 WildFly Swarm 入门

Hello World 就像前面章节中的其他框架一样,我们希望添加一些基本的 Hello-world 功能,然后在其上逐步添加更多的功能。让我们从在我们的项目中创建一个 HolaResources 开始。您可以使用您的...

woshixin ⋅ 31分钟前 ⋅ 0

Maven的安装和Eclipse的配置

1. 下载Maven 下载地址 2. 解压压缩包,放到自己习惯的硬盘中 此处我将其放到了 D:\Tools 目录下。 3. 配置环境变量 右键此电脑 -> 属性 -> 高级系统设置 -> 环境变量。 在系统变量中新建,变...

影狼 ⋅ 38分钟前 ⋅ 0

python pip使用国内镜像的方法

国内源 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 华中理工大学:http://......

良言 ⋅ 39分钟前 ⋅ 0

对于url变化的spa应该如何使用微信jssdk

使用vue单页面碰上微信jssdk config验证失败的坑。第一次成功 之后切换页面全部失败,找到了解决方法,第一次验证成功后保存验证信息 切换页面时验证信息直接拿来用,加一个wx.error() 失败时...

孙冠峰 ⋅ 43分钟前 ⋅ 0

Spring Cloud Gateway 一般集成

SCF发布,带来很多新东西,不过少了点教程,打开方式又和以前的不一样,比如这个SCG,压根就没有入门指导,所以这里写一个,以备后用。 一、集成 pom.xml <dependency> <groupI...

kut ⋅ 47分钟前 ⋅ 0

建造模式

《JAVA与模式》之建造模式

Cobbage ⋅ 今天 ⋅ 0

WePY框架开发的小程序如何在微信web开发者工具中运行起来

一、首先需要安装node.js,安装步骤如下: 首先下载安装包 https://nodejs.org/en/download/ 点击下载相应的zip版本 然后将文件夹解压到任意目录 比如我这里解压到了:C:\Program Files\node...

Helios51 ⋅ 今天 ⋅ 0

使用EnumSet 代替位域(32)

1、位域(Bit field):使用or 运算将几个常量合并到一个集合中 位操作,可以有效地执行 AND 、OR 这样的位操作 但是 位域比int 常量枚举缺点更多 2、java.util 包里面的EnumSet 类是有效的替...

职业搬砖20年 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部