基于Android的人脸识别软件设计_第1页
基于Android的人脸识别软件设计_第2页
基于Android的人脸识别软件设计_第3页
基于Android的人脸识别软件设计_第4页
基于Android的人脸识别软件设计_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊毕业设计(论文)报告纸《基于Android的人脸识别软件设计》摘要随着深度学习技术的进步和android手机的不断普及,人们对美颜的需求也越来越高,因此基于深度学习的美颜相机逐渐成为了当前社会的热门应用,占据了大量美颜应用市场。该毕业设计主要采用多任务卷积神经网络(MTCNN)实现人脸检测及双边滤波算法实现人脸的磨皮美白。多任务卷积神经网络是通过三个CNN模型实现,第一层卷积神经网路由于层数浅,可以快速产生疑似人脸的候选窗口,第二层卷积神经网络根据置信度排除绝大部分的非人脸的候选窗口,第三层卷积神经网络寻找五个人脸上特征标记点。双边滤波算法是一种非线性滤波,它是通过使用两个高斯滤波来实现的,一个负责计算空间接近度的权重,另一个负责计算像素值相似度的权重,从而可以实现滤波同时,边缘也不模糊。该美颜相机应用适用于Android4.1版本以上的手机。关键字多任务卷积神经网络,双边滤波算法,BB回归,标记定位,高斯滤波,卷积ABSTRACTWiththegrowingpopularityofmobilephonesandandroidprogressdeeplearningtechnology,thedemandforbeautyhavebecomemoresophisticated,sothecameradepthstudybasedonbeautygraduallybecomeapopularapplicationofcurrentsociety,occupyalargemarketapplicationsbeauty.Thegraduationprojectmainlyusesmulti-taskingconvolutionneuralnetwork(MTCNN)forfacedetectionandbilateralfilteringalgorithmdermabrasionwhiteningface.MultitaskingconvolutionalneuralnetworkmodelisimplementedbythreeCNN,afirstlayerofaconvolutionalneuralnetworksincetheshallowlayers,canquicklygeneratepseudocandidatefacewindow,thesecondlayerofnegativevastconvolutionalneuralnetworkbasedontheconfidencenon-facecandidatewindowportion,thethirdlayerconvolutionalneuralnetworktofindfivefacefeaturemarkpoints.Bilateralfilteringalgorithmisanon-linearfiltering,whichisimplementedusingtwoGaussianfiltering,oneforweightcalculationofthespatialproximity,anothercomputingpixelvaluesimilarityresponsibleweight,dosoatthesametimefiltering,itdoesnotblurtheedges.ThebeautycameraappformorethanAndroid4.1versionofthephone.KEYWORDSMultitaskingconvolutionneuralnetwork,Bilateralfilteringalgorithm,boundingboxregression,Landmarklocalization,Gaussianfilter,convolution目录TOC\o"1-3"\h\u25757第一章绪论 524281.1选题背景及意义 5260111.2国内外相关研究现状 6141391.2.1人脸识别技术 6322121.2.2美颜 8284911.3本文主要工作 1092351.4本文主要结构 1080391.5系统的开发环境和运行环境 10211第二章算法介绍 11166472.1MTCNN 11304492.1.1MTCNN概述 11178702.1.2原理 11191612.1.3涉及到的技术 15236822.2双边滤波算法 1692392.2.1双边滤波概述 16314522.2.2双边滤波原理 17175232.2.3双边滤波的公式 17150172.2.4双边滤波的权值分布 1926890第三章算法实现 20197263.1MTCNN模型实现与训练 20115143.1.1下载训练集并进行处理 2074193.1.2训练模型 22170503.2构建APP实现摄像头预览 23169013.3载入模型 25162213.4实现菜单 28120963.5实现渲染 29224703.6实现美颜 3096893.6.1美白 3051523.6.2磨皮 30290473,6.3红润 3030343.6.4实现Android拖动条(SeekBar) 31257753.7实现滤镜 31257653.7.1模糊滤镜 31322723.7.2黑白滤镜 31317063.7.3四分滤镜 318846结论 325035致谢 3291主要参考文献 3227427附录 33第一章绪论1.1选题背景及意义在当今社会,对美丽的热爱是普遍的。无论男女老少,尤其是女性用户,这都是不可避免的。根据数据,美颜相机是世界上第一个为自拍开发的移动美颜APP。推出后仅88天,用户总数已达到2000万,而用户数量仍在迅速增长,一年后超过了1亿。在其用户中,绝大多数是女性,比例为2.8:7.2。随后,大量的美颜应用如B612咔叽,美图秀秀等相机应用软件开始出现。随着这些美颜软件的诞生,为人们提供了更多展示自己的机会,也掀起了一股美容自拍浪潮。据统计,自拍照的图像每三秒钟在世界各地上传一次,自拍照用户花费更多的时间美化自己的照片,而不是化妆。在这一浪潮中,各种美容photoshop应用程序已成为自拍照片的生产线。在将“合格的”自拍照照片上传到QQ空间和微信之前,通常会对其进行一些美容处理和修改:皮肤打磨,美白,红润,瘦脸等。这样,由获取,修复和上载组成的固定格式已成为一种流行的生活方式,人们因此进入了“自拍照”时代。在此过程中,人们开始对一般自拍美颜不再满意,逐渐演变为对各种新奇的活动,因为美颜软件也开始开展一些新颖的活动来吸引更多用户的注意力,例如百度魔图PK大明星,让用户看到与名星的相似程度;在万圣节时期进行的万圣节化妆贴图;进行偶像营销的美颜相机。然而这些并没有改变美颜类应用的颓势,由于功能相似,性能差不多,导致用户对其都是三分钟热度。这段时间听说这个好用就用这个,等过段时间发现那个应用人多就用那个,无论那个APP都不存在粘性,新奇的活动只能短暂吸引用户眼球,等热度过了,用户又会悄然流失。如何进行用户沉淀,如何吸引住用户,阻止用户溜走,提高用户忠诚度,最最关键的还是新技术的引入和性能效果的提升。这时,人脸识别技术进入了飞速发展,出现了许多技术方法,尤其是自1990年以来,人脸识别技术已经得到长远的发展,每年都有非常多的学术论文出现在官方网站发表。人脸识别算法主要包括:基于神经网络的识别算法,基于几何特征的识别算法,基于模板匹配的识别算法,基于面部特征点的识别算法等。其中,基于深度学习的人脸识别以其较高的识别率和快速的识别效率超越了传统的人脸识别,逐渐成为整个领域的核心技术。大量的人才、学术界、工业界和个人爱好者都投入到该技术的研究中,成为其研究力量的生力军,发展趋势进入高速发展中。基于深度学习的人脸识别不仅在公开发布的公共测试集上不断刷新纪录,同时也已经成功应用到金融安全、智能安全防护和银行系统等领域。如今,几乎所有知名的IT公司和理工大学都设有研究小组从事与面部识别相关的主题。如果将人脸识别技术应用在美颜类的应用上,其性能将得到大幅度的提升,不仅可以增加与用户之间的互动,还可以是美颜更加精细化,使美颜不再是对整体进行,而是只针对你的人脸部分,甚至是眼睛,鼻子都可以进行微调。1.2国内外相关研究现状1.2.1人脸识别技术国外:1966年,PRI的Bledsoe开始致力于机器的自动面部识别。1990年,日本开发了人像识别机,可以在一分钟内从21万人中识别出所需的人。1993年,美国陆军研究实验室(ArmyResearchLaboratory)和高级研究计划局(AdvancedResearchProjectsAgency)成立了Feret(FaceRecognitionTechnology)项目团队,该团队创建了Feret人脸数据库,该数据库可用于检测人脸识别算法的效率。2012年,联邦调查局(FBI)投资了10亿美元开发面部识别技术数据库。美国是第一个开始使用人脸识别技术的国家,也是世界上第一个应用此技术的国家。美国的人脸识别技术始终属于世界顶级水平。1993年,美国国防部启动了FERET项目,为以后研究生物智能识别技术奠定了良好的基础,并将人脸识别技术从最初的阶段推广到了原型系统阶段。现在,美国电影中的现象:没有钥匙孔,只有相机的门,您可以通过识别脸部进入房间。通过面部识别可以解锁政府部门中的关键设备。在美国,已经在使用预先安装的摄像头在跟踪人时识别面部。2014年,FBI推出了最新一代的电子身份识别系统,该系统可以使用摄像头跟踪嫌疑犯,并带领他们进行人为追捕,耗资超过10亿美元。美国陆军实验室使用使用VC++开发的软件来实现该技术。人脸准确性识别率为49%。在美国公开发布的测试培训中,FAR为53%。美国国防部高级研究计划(DARPA)使用半自动和全自动算法。该算法需要预先识别图像中人脸的手动和自动眼中心坐标。在机场的现场测试中,识别准确率很低,系统中存在很多错误和错误。日本虽然稍微晚些接触到人脸识别的国家,但是日本的面部识别技术发展迅速。早在2014年,日本大阪的一个研究中心就测试了基于视频流的面部识别技术。该项目的目的是通过摄像头实时监控面部表情和人流,以确定在发生灾难时紧急出口是否可以安全使用。近年来,日本一直在加快对智能视频分析的研究。2015年,日本日立公司开发了视频监控人脸识别技术,该技术可以每秒扫描3600万张图像,其技术形式为高级识别人脸,并实时存储人脸图像以对相似的人脸图像进行分类。2015年7月3日,日本所有主要机场都使用了可以通过计算机智能识别人脸的系统。卡内基梅隆大学,麻省理工学院和英国雷丁大学等一些外国大学,此外,还有上市公司的研究方向(有远见的专家,Viaage的FaceFINDER身份验证系统,LauTech的Hunter系统),德国的BioID系统)也主要集中在公共安全,刑事侦查和安全方面,而实际上对考试验证系统的方向还没有进行深入的研究。国内:在中国,从人工识别发展到计算机智能识别的最早的生物识别技术是从指纹识别技术开始的。然而,在实际的测试和应用中,对人脸识别技术的需求逐渐显现。与国外相比,中国人脸识别技术的发展时间相对较晚,但发展速度很快。早在1990年代,中国就开始研究人脸识别的方向,并建立了各种研究机构和相应的机构。清华大学最优秀,最具代表性的学校和科研机构,自动化系,电子与计算机科学系,中国科学院制动学会模式识别国家重点实验室和哈尔滨工业大学计算机系等的表现在面部识别和其他模式识别领域,研究团队,研究机构和学校尝试了许多重要的测试和实践,并取得了显著成果。随后,越来越多的专家,博士生和学者参加了人脸识别研究项目,并发表了许多有价值的高水平文章。自2001年以来,中国公安刑侦部门一直在使用面部识别技术预防和打击重大刑事犯罪,并得到了政府资金的大力支持。然后,在2002年,北京克里基科技发展有限公司成立。成功实施了人脸识别系统,首次可以达到50%的正确识别率。2005年1月18日,由清华大学电子学系人脸识别研究组组长苏光大教授主持的人脸识别系统通过了公安部专家组的评审。专家一致认为,人脸识别技术处于国际先进水平和中国领先水平。2006年,方正科技集团有限公司推出了新的笔记本电脑,这是中国第一台具有“面部识别”功能的笔记本电脑。在2008年北京奥运会期间,中国首次在安全系统中采用了面部识别技术,为奥运会的顺利开幕提供了有效的安全措施。这也标志着家用人脸识别技术进入了大规模的应用和实践阶段。总的来说,早在19世纪末,法国人就如何利用面部特征来识别人的问题发表了报纸和杂志报道。直到20世纪末,人脸识别技术才取得了根本性突破。面部识别技术的发展主要经历以下三个阶段:第一阶段主要研究简单背景下的面部识别以及面部识别过程中所需的面部特征。Bledsoe的研究被认为是面部识别研究的开始。在1960年代中后期,人们使用脸部器官的局部特征来描述脸部,但是这种方法仅对正面脸部变形较小的脸部产生了一些影响。1970年代,一些研究人员使用计算机建立了高质量的面部灰度图像模型。在这个阶段,面部图像的识别过程几乎与操作者密不可分,并且所构造的系统不能自动完成识别任务。但这对于设计识别面部的算法和系统的工程师来说是重要的指南。第二阶段主要集中在人机交互的人脸识别上。Lesk和Harmon使用几何特征参数和多维特征向量来描述人脸图像信息,并基于此思想开发了图像识别系统。Kobayashi和Kaya将统计识别理论整合到面部识别中,并使用欧几里得距离来描述面部特征,例如嘴唇与鼻子之间的距离。Stonham提出了一种用于面部识别和表情分析的单层自适应神经网络,每个人一个。这个阶段并没有摆脱人工干预,但是仍然需要操作人员具备一些先验知识。第三阶段是自动机器识别阶段。在1990年代,随着计算机结构的不断改进,计算速度和效率也在不断提高,图像获取和处理能力也得到了提高,人脸识别方法取得了重大突破。它不仅可以自动识别正面,光线充足且没有阴影的面部,而且还可以识别具有不同姿势变化,不同表情,不同年龄阶段和不同光照条件的面部。在这一阶段,研究人员提出了许多自动人脸识别方法,在一定程度上促进了人脸识别技术的发展。1.2.2美颜在手机刚开始起步时,人们对手机的需求并不是很大,只要能够完成基本的通讯功能就足够了。之后,随着科技的发展,手机进入到了功能机时代,手机厂商开始在手机内部添加一些新的功能应用,例如听音乐,拍照片等等,所以演变成两大主流手机:音乐手机和影音手机,后来这些都成为每部手机必备的应用软件了。到了智能机时代,人们对手机需求开始上升,手机厂商经过调查发现,女性市场占据主要部分,且女性消费者最为关注的手机功能就是自拍美颜效果,换言之,只要哪个厂商能够在自拍的美颜技术上形成技术压制,自然就能占据女性消费者市场。因此手机厂商开始想方设法在提升美颜技术。刚开始,手机自带的相机中的美颜功能并没有比得过软件的美化,因为前期的手机厂商在相机美颜功能上只是随意的将皮磨平,之后再对亮度进行调高。所以,在当时,美图软件还是占据主流地位的。后来OPPO对美颜进行深入大量的研究,创造了自己的一套美颜自拍的算法,将其应用到了手机上,得到了大量的女性消费者的认同,因此虽然手机硬件配置不高,但依旧占据了一大批的市场,并且进入当时市场排名前三,取得了巨大的成功。这样导致其他很多厂家十分眼红,大家纷纷效仿,手机美颜自拍功能得到了巨大的发展。Vivo紧随其后,增加手机前置摄像头至两个,将美颜自拍功能作为手机的卖点之一,也取得成效显著的成功。现如今,美颜已经不再是只依靠一个算法,它还结合着当下最热的深度学习技术,模仿人们平时化妆的步骤,实现逐层自拍美颜的效果。美丽时代的人看起来更加美丽,也没有隐藏对美的追求。美丽时代终于使美丽黯然失色。美丽不再供不应求,为容貌被压抑的事物留出更多空间。在世界各地,每三秒钟,网络冲浪者就会上传一张自己的照片,花费更多的时间来美化照片而不是化妆。这似乎已经建立了一种新的社会规范,例如需要在正式场合穿着西装,在这种场合下,不给自拍照增添魅力的自拍照会成为一种陌生的景象,并成为一种礼貌的形式。2013年,在牛津英语词典宣布“selfie”为年度单词后的12个月中,英语世界中“selfie”的出现频率飙升了170倍。世界各地的每一秒钟,网络冲浪者都会尝试通过Internet查找自拍照的图像,然后每三秒钟,网络冲浪者就会上传一张自拍照的图像。这种趋势也激发了自拍用户想象自己的形象,各种各样的照片编辑应用程序正在成为一些亚洲国家的规范,皮肤抛光,美白和脸部变薄比化妆要花费更多的时间。Instagram是一个过滤器丰富的应用程序,预计每天将产生7500万张自拍照。一方面,它表现出一种修正的自我和一种未改变的自我期望。另一方面,它形成了新的社会法。对于美图秀秀的创始人吴新红来说,相机的诞生纯粹是由数据驱动的。他发现根据美图秀秀的数据,“人像美”已经超越“美化”,成为最常用的功能模块。所谓的“人像美”就是使用按键打磨,按键美白的方式美化人像照片。用“美白”,“瘦脸”和“去除粉刺”等术语代替“白平衡”,“积极负面影响”和“高ISO降噪”降低了以前不得不求助于专业人士的自拍照使用者的门槛缓凝剂。摄像机通过一个按钮在几秒钟内完成所有美化工作,从而进一步简化了过程。“美图的最大优势是对女性的了解。”“美图产品副总裁陈杰说。他和他的团队买了“女人的起源”来研究女人的心理,办公室里的女人成了优秀的测试对象。在美图的办公室里,自拍照工人蹲在角落里为了适应女性的审美观,UI设计色彩的风格小巧而清新,以“卡哇伊”风格装在车架上,以适应女性的审美观。一个新的想法:美将产生一种“金光闪闪”的动画效果,灵感来自于动画“水手月亮”,当水变成冰月时,到处都是花朵和星星。这样就开始了社交自拍的热潮。如今,美容相机每天产生1亿张自拍,并分布在社交媒体平台上,二十一点是最流行的自拍时间。天秤座是最受欢迎的自拍照标志,占所有用户的21%,其中男性占18%。浴室还是唯一地点。自言自语比单词更能满足人们对印象管理的需求。尽管自拍者需要控制他人对他或她的看法,但文字的线性本质并不能反映人类情感的复杂性。对虚拟社会心理学的一项研究表明,图片使人们感觉就像面对面接触。人们有意识地选择具有自己形象的形象,既要表现自己的外观,又要突出对他们来说很重要的特征和品质。”未来,人脸识别技术的发展将大大扩大美容效果的可能性。通过机器学习,可以根据每个人的面部特征优化美容产品。例如,在机器看到许多这样的面孔之后,它可以匹配相应的星星。他说:“我们现在拥有一种称为“一键式,独立的,内置软件的离线应用程序”。吴先生说:“将来,它将通过'云'。”“我们可以群集服务器并进行更复杂的处理。”1.3本文主要工作本文的目的是实现人脸区域的磨皮美白的安卓应用APP。要实现这样的效果,首先需要选定人脸的区域范围,这就要运用到当下热门的深度学习的神经网络,学习MTCNN原理,利用先前在本地端训练好的MTCNN模型获得人脸轮廓范围,然后了解双边滤波器的原理,最后利用双边滤波的方式进行人脸磨皮,达到不改变人脸边缘的前提下实现美化人脸的目的。1.4本文主要结构本文的章节做如下安排。第一章绪论主要是介绍该毕业设计的背景及意义、相应所需要的技术在国内外发展状况以及开发该系统所需要的开发环境和运行环境;第二章算法介绍主要是对MTCNN模型和双边滤波算法进行详细的介绍与说明;第三章算法实现主要以图文的形式讲述MTCNN模型是如何进行建立和训练的以及双边滤波是如何应用的。结论是对整个毕业设计工作的归纳与总结,通过比较总结出自己设计工作的合理性,对其中优点和不足之处提出自己个人的改进意见与看法;致谢主要内容是对指导自己的导师表示感谢;主要参考文献所列出的是我曾经了解过帮助很大且发表在公开出版物上的论文或者是网上下载的在设计中所使用的资料。附录主要放置的是有参考价值的程序但不适合放到正文中。1.5系统的开发环境和运行环境PyCharm2019.1.2(ProfessionalEdition):PyCharm是由JetBrains创建的PythonIDE,并带有许多工具,可帮助您更高效地用Python编写代码,例如代码跳转,智能提示,语法突出显示,项目管理,自动完成,单元测试,调试,版本控制等等。此外,IDE具有许多高级功能,可用于在Django框架下支持专业的Web开发。它还支持GoogleAppEngine,而PyCharm还支持IronPython,借助高级代码分析程序,PyCharm成为了专业Python开发人员和初学者的便捷工具。AndroidStudio3.6.1:AndroidStudio是一个类似于EclipseADT的基于IntellijIDEA的Android开发和编译环境。AndroidStudio提供了用于开发和调试的集成Android开发工具。它基于IDEA,还基于Gradle构建支持,基于用于生成常用Android应用程序和组件设计的模板指南,提供了诸如版本兼容性,可用性,捕获性能问题之类的快速工具。布局功能强大的编译器,可以在控件预览上使用窗体拖动效果,可以重建Android专有和快速修复,还支持Progard标志和应用程序。Anaconda4.7.12:Anaconda是专门用于方便使用的Python科学研究数据,并建立了一套软件包,涵盖了几乎所有常见的Python库数据科学领域,并且专门用于解决依赖CONDA软件包管理系统的软件环境问题。是提供包管理和环境管理的功能,可以非常方便地解决多个版本的Python切换,共存和各种第三方包的安装问题。Anaconda可以使用工具命令conda进行安装和环境管理,并且它已经包含Python和相关工具。Tensorflow-gpu1.14.0:TensorFlow是当前世界上最受欢迎的深度学习框架,主要用于语言理解,图像识别,语音理解等领域。它灵活,快速,适合于产品和大规模应用。TensorFlow使用计算图执行所有计算。计算表示为tf.graph对象的实例,其中数据表示为tf.tensor对象,该对象使用tf.operation对象进行使用和操作,然后在Session中使用tf.session对象执行。由于Tensorflow的GPU版本训练速度更快,所以还需要下载对应的CUDA(用来实现GPU运算的平台,利用显卡进行训练)和CUDNN(加速神经网络),因此该毕业设计中的配置如下:Cuda10.0+Cudnn7.4.2+Python3.7+Tensorflow-gpu1.14.0算法介绍2.1MTCNN2.1.1MTCNN概述MTCNN又称多任务卷积神经网络(Multi-taskconvolutionalneuronetwork),是由中国科学院深圳研究院于2016年专门针对人脸检测的多任务神经网络模型提出的,该模型主要采用三种级联网络,利用候选框和分类器的思想,快速高效地进行人脸检测。这三个级联网络是p-net(可快速生成候选框),r-net(可高精度筛选和选择候选框)和o-net(可生成最终边界框和面关键点)。该模型还使用非最大抑制,边界回归,图像金字塔和其他技术。2.1.2原理上图是MTCNN论文原图,上面清晰明了显示了MTCNN的原理流程,我将其分为以下四个步骤:构建图像金字塔。首先对图片进行不断的Resize,就会得到一系列尺寸大小不同的图片,以适应不同大小人脸的检测。按照MTCNN论文所述,调整大小的比例为0.7,这个数值可以自己根据下载的数据集中人脸大小以及分布来赋值,最好还是控制在0.70-0.80之间较为合适,如果设置的比例过大,就会造成处理时间过长;如果比例太小的话,就会漏掉一些小型和中型人脸。按照调整大小的比例对图片进行缩放,直到图片的大小大于或者等于Pnet要求的12*12的大小。如此,我们就会得到原图、原图*0.7、原图*0.7^2...、原图*0.7^n(最后一张图片大小会大于或者等于12),这一系列尺寸大小不同的图片,由于堆叠起来好像是个金字塔,又被称为图片金字塔,最后将这些图片一张一张地输入到Pnet中去得到候选。P-Net。全称是ProposalNetwork,其本质就是一个全连接的卷积神经网络,这个网络将特征输入三个卷积层之后,通过人脸分类器来判断该区域是否为人脸,同时使用边框回归和非极大值抑制,最后将会输出许多疑似存在人脸的区域,然后将这些疑似区域输入到R-Net中进行更细致的处理。通过第一步,我们可以获得一系列不同大小的图像,即图像金字塔,并将所有这些图像输入到Pnet中。我们可以通过FCN进行初步的特征提取和边界校准,并进行候选框的边界框回归调整和大多数候选框的NMS过滤。简单来说P-Net的思想就是使用较为浅层、简单的CNN网络来实现快速生成疑似人脸候选框。R-Net。全称是RefineNetwork,其本质是一个卷积神经网络,它为第一层p-net网络增加了一个完全连接的层,从而使其在过滤输入图像方面更加复杂。图像通过p-net网络后,将出现大量预测窗口,我们将其发送到r-net网络,它将过滤掉许多不符合要求并具有良好性能的候选框。最后,将通过边界框回归和NMS对剩余的候选框进行优化和再次预测。由于P-Net网络的输出只是一些具有一定置信度的疑似人脸区域,在该网络中,可以对输入的图像进行更加精细的选择,同时过滤掉绝大部分错误的输入,并且再一次使用边框回归和非极大值抑制来进行人脸区域的优化,最后将会输出置信度较高的疑似人脸区域,将这些输入给O-Net使用。相比于P-NET使用全卷积来输出1*1*32的特征,R-Net采用的是在最后一个卷积层之后使用了一个128的全连接层,保留住了更多的图像特征,准确性也能较优与P-Net。简单的来说就是R-Net的思想就是采用一个比P-Net更加复杂的网络结构来对P-Net所认为可能是人脸区域的候选框进行进一步的筛选和调整,进而达到高精度滤除和人脸区域优化的效果。O-Net它的全称是OutPutNetwork,其本质是一个相对复杂的卷积神经网络,与r-net相比,它具有一个额外的卷积层。o-net和r-net之间的差异在于这一层,它将通过更多的监督来识别面部的面部区域,并对面部的面部特征点进行相应的回归。最后,将会输出五个人脸的面部特征点。相比于R-Net,这是一个更加复杂的卷积网路,这个网络的输入特征会更加多,在网络结构的最后一样是一个更大256的全连接网络层,保留更多的图像特征,然后进行人脸判别、人脸区域边框回归和人脸特征定位,最后输出人脸区域的左上角坐标和右下角坐标及人脸区域的五个特征点。由于O-Net拥有更多的特征输入及更加复杂的网络结构,也因为其更好的性能准确率,所以将这一层的输出结果作为整个网络模型的最终输出。简单来说O-Net与R-Net的思想殊途同归,都是采用更加复杂的网络对模型的整体性能进行优化,提高其人脸检测的准确性。2.1.3涉及到的技术FNC:全称全卷积网络,它是除传统的卷积网络连接层之外,然后对最后的卷积层特征图样本进行去卷积,以能够恢复到原始图像大小,并且反卷积图像的每个像素都可以预测一个类别,同时保留原始图像的空间信息。IOU:对于图像的子目标图像和用于校准子目标图像的预测框,最终校准的预测框和真实子图像的自然框(通常需要手动校准)之间的相关性称为IOU(联合上的交集),经常使用的标准是两个盒子的横截面积和合并面积之和。Bounding-Boxregression:全称边框回归,对于一个框,我们经常使用四个维向量(x,y,w,h)来表示盒子,其中x和y代表窗口的中心点坐标,而w代表h的宽度和高度。在下图中,红色框P表示原始框,绿色框G表示目标框,线性回归是为了找到一种关系,以便将输入的原始窗口P映射到更接近回归窗口G^真实窗口G。非极大值抑制(Non-MaximumSuppression,NMS):简而言之,它是抑制非最大值的元素。例如,在行人检测项目中,滑动窗口提取行人特征,并在由分类器分类识别后,每个窗口将获得相应的分数。但是,滑动框可能会导致许多框包含其他框或几乎与其他框复制。然后,使用NMS选择附近得分最高的框,并取消得分最低的框。就像上面的图片一样,找到一辆汽车,算法会找到一堆盒子,我们需要找出哪些盒子没用。非最大抑制方法如下:首先,假设有六个矩形框,根据分类器的分类概率对其进行排序,并假设从小到大的属于车辆的概率为A,B,C,D,E和F。(1)以最大的概率从矩形框F开始,判断A〜E与F的重叠度IOU是否大于A的某个阈值;(2)如果B和D之间的重叠度超过阈值,则丢弃B和D;我将标记第一个矩形F,我们将其保留。(3)从剩余的矩形框A,C和E中选择概率最高的E,判断E与A和C之间的重叠度。如果重叠度大于A某个阈值,则将其丢弃;E是我们保留的第二个矩形。重复并找到所有剩余的框。顾名思义,非最大抑制(NMS)是抑制非最大值的元素,以搜索局部最大值。此局部表示具有两个变量参数的邻域,一个是邻域的维数,另一个是邻域的大小。此处不讨论通用NMS算法,而是将其用于提取目标检测中得分最高的窗口。例如,在行人检测中,提取滑动窗口的特征,并由分类器分类和识别后,每个窗口将获得一个分数。但是,滑动窗口可能会导致许多窗口包含其他窗口或大部分与其他Windows相交。在这种情况下,需要NMS选择得分最高(行人概率最高)的那些街区,并禁止得分最低的那些窗口。2.2双边滤波算法2.2.1双边滤波概述双边滤波,也称为BilateralFilter,是一种非线性滤波。这是一种将图像的空间接近度与像素值相似度相结合的方法。在滤波时,该滤波方法同时考虑空间接近度信息和颜色相似度信息,在滤除噪声并使图像平滑的同时,还实现了边缘保留。双边滤波使用两个高斯滤波器的组合。一个负责计算空间接近度的权重,即常用的高斯滤波原理。另一个负责计算像素值相似度的权重。在两个高斯滤波器同时作用下,是双向滤波。双边过滤器的优点是可以用来保留边缘。通常采用高斯滤波来减少噪声,这会使边缘模糊更加明显,并且对高频细节的保护效果不明显。顾名思义,双边滤波器比高斯滤波器多一个高斯方差sigma-d,并且高斯滤波器是基于空间分布的高斯滤波器函数。因此,在边缘附近,像素越远,对边缘像素值的影响越小。它保证了边缘附近像素值的保留。但是,由于保留了太多的高频信息,对于彩色图像中的高频噪声,双边滤波器无法干净地滤除,而只能很好地滤除低频信息。2.2.2双边滤波原理双边滤波的原理是将与空间距离有关的高斯函数与灰度距离有关的高斯函数相乘。空间距离:指当前点到中心点的欧氏距离。高斯函数在空间域的数学形式为:其中(xi,yi)为当前点位置,(xc,yc)为中心点的位置,sigma为空间域的标准差。灰度距离:为当前点灰度值与中心点灰度值之差的绝对值。高斯函数在值域内的数学形式为:其中gray(xi,yi)为当前点灰度值,gray(xc,yc)为中心点灰度值,sigma为为值域标准差。对于高斯滤波,仅在将空间距离权重系数的核与图像卷积后才能确定中心点的灰度值。也就是说,点离中心越近,其权重系数就越大。在双边滤波中,增加了灰度信息的权重,即在邻域,灰度值接近中心点的灰度值的点的权重越大,其灰度值差异很大的点的权重越小。权重由高斯函数的值域确定。将空间权重系数乘以灰度权重系数,便得到了最终的卷积模板。由于双边滤波需要每个中心点域的灰度信息来确定其系数,因此其速度比一般滤波要慢得多,并且计算的增长率是核心大小的平方。2.2.3双边滤波的公式G(I,j)代表输出点;I,j的S是以(I,j)为中心的2N加1(2N加1)的大小;F(k,l)代表(多个)输入点;W(I,j,k,l)表示由两个高斯函数计算的值。我们假设公式中的w(I,j,k,l)为m,则对上面的公式进行变换,设m1+m2+m3…+mn=M,则有现在可以看到,这显然是图像矩阵与内核的卷积。其中,m1/M代表第一个点的权重值,图像矩阵和核由卷积算子加权和求和,最终得到输出值。现在让我们讨论w(I,j,k,l)。Ws是空间邻近高斯函数,wr是像素值相似度高斯函数。如图所见,w是ws和wr的乘积。对于ws,这是一个普通的高斯滤波器函数,其坐标被替换。Sigmas是程序输入值,并且该函数是根据空间接近度计算的。wr正在计算像素值(色彩空间)的相似度,请注意,这是高斯替换坐标值,即2sigmar^2以上的范数,即|,f(I,j)-f(k,l),|^2。那是两点之差的绝对值的平方。其中,在计算彩色图片的差值时,应减去(I,j)点的RGB通道值之和减去(k,l)点的RGB通道值之和。这是一种色彩空间计算,不是作为单个通道进行的,而是在矩阵的最终卷积中,它是单个通道乘以权重而不是三个通道的总和。2.2.4双边滤波的权值分布当图像位于平坦变化的区域中时,附近的像素值(RGB值)之差不大。此时,wr无限地接近于1,因此这时的两侧都是普通的高斯滤波,以实现图像平滑的效果。当图像处于边缘区域等急剧变化的区域时,相邻区域的像素值(RGB值)之差非常大。此时,wr接近0,色差越大,wr越接近0,最终整个表达式的值接近0。最终权重为0。因此,这不会影响输出。最终计算中的值。通过这种方式,不仅能平滑图像,又能保持了图像的边缘不模糊。算法实现3.1MTCNN模型实现与训练3.1.1下载训练集并进行处理进入http://shuoyang1213.me/WIDERFACE,下载训练集WIDERFaceTrainingImages以及标签Faceannotations,解压后放置到original_data中,进入http://mmlab.ie..hk/archive/CNN_FacePoint.htm,下载训练集Trainingset,解压后放置到original_data中。处理训练集的标签由于训练集的标签,如下所示:0--Parade/0_Parade_marchingband_1_849.jpg1449330122149000000而我们需要的是这样的:-Parade/0_Parade_marchingband_1_849.jpg449330571.0479.0因此需要对训练集的标签进行处理,我们通过查看压缩包里的readme.txt的说明,可知第一行为文件路径,第二行为图中人脸数量,第三行是人脸信息参数分别为:x1,y1,w,h,blur,expression,illumination,invalid,occlusion,pose。x1,y1,w,h,代表人脸框的位置;blur:是模糊度,分三档:0,清晰;1:一般般;2:模糊不清;express:展示形式illumination:曝光,分正常和过曝occlusion:遮挡,分三档。0,无遮挡;1,小遮挡;2,大遮挡;invalid:无效状态pose:(典型和非典型姿态)由于我们只需要图片路径和x1,y1,w,h,所以编写了一个函数transformTxt专门用来处理标签问题。transformTxt(original_txt_path,final_txt_path)函数的原型如附录所示,输入两个参数分别为原先数据集的标签地址及之后保存处理后的标签地址。ⅰ以写入得方式打开之后保存处理后的标签地址,以只读的方式打开原先数据集的标签地址;ⅱ调用file.readlines()以一行一行的形式进行读取,先去除头尾空格,之后判断其是否为“jpg”结尾,如果是的话,说明是文件路径名,将其写入到写入文件中,如果不是的话,就跳过,最后将其标志改为TRUE。ⅲ获取人脸数量,由于一行一行读取,因此文件名后为人脸数量,只要判断标志是否为TRUE就行了,如果为TRUE,就将其赋值给sum,将其标志赋值为FALSE,判断sum是否为零,若为零,将数量标志赋值为TRUE,否则就跳过。ⅳ处理人脸数量为零的图片,判断数量标志,若为TRUE,则删除该行,并将数量标志重置为FALSE。ⅴ判断是否为人脸图像坐标x,y,w,h,先判断sum是否大于零,如果大于零,则说明图像有人脸则进入双重for循环,以挨个将人脸图像坐标提取出来,依次写入写入文件中。如果为零或者小于零,跳过。处理训练集图片由于PNet是全卷积网络,其目的是为了应对不同人脸情况,如果只训练有人脸会造成识别正确率下降,将无人脸的时候识别出人脸。为了提高识别准确率,训练数据由四部分组成:pos,part,neg,landmark,分别表示有人脸,部分人脸,无人脸及关键点,比例为1:1:3:1。ⅰ以只读的形式打开处理过的标签存放地址,调用file.readlines()函数读入,使用FOR循环来以一行一行的形式读入。ⅱ调用line.strip().split('')将一行内容以空格的方式分割赋值给字符串数组str。ⅲ读取图片,由于每行第一个为图片地址名,故直接调用cv2.imread读入图片,将之后的坐标信息,用FOR循环以四个为一列保存boxes的链表中。ⅳ通过for循环调用boxes中的每个人脸坐标信息,通左右上下坐标计算宽高,判断宽高来舍去图像过小和在图片之外的图像。ⅴ做五次for循环,生成非人脸的图像,调用np.random.randint函数随机生成的关于x1,y1的偏移量在,并且保证x1+Offset_x>0,y1+Offset_y>0和之后与原先不重合。截取偏移后后的左上角坐标,排除大于原先图片尺度,截取box,计算IOU,截取图片并resize成12x12大小image[y1:y2,x1:x2],使用双线性插值法,缩放图片至12*12,将IOU值小于0.3判定为非人脸图像,保存截取图片及其labol。ⅵ通过FOR循环二十次,并缩小随机选取size范围,更多截取pos和part图像。除去尺度小于5的,将偏移量,范围缩小为原来的五分之一,截取图像左上坐标计算是先计算x1+w/2-size/2坐标,再加上偏移量,计算新的左上角坐标,排除超出的图像,截取box,人脸框相对于截取图片的偏移量并做归一化处理,截取图片并resize成12x12大小image[y1:y2,x1:x2],使用双线性插值法,缩放图片至12*12,判断IOU是否大于0.65,如果大于0.65,则将其列入人脸图像,如果小于0.65,大于0.4则列入部分人脸中,并将图片地址及相应的人脸坐标信息写入相应标签文件中ⅶ将人脸图像的状态定为1,部分人脸图像的状态定为-1,非人脸图像的状态定为0。3.1.2训练模型MTCNN主要训练三个神经网络PNet,RNet,ONet。将目录cd到preprocess上,pythongen_12net_data.py生成三种pnet数据,pythongen_landmark_aug.py12生成pnet的landmark数据,pythongen_imglist_pnet.py整理到一起,pythongen_tfrecords.py12生成tfrecords文件将目录cd到train上pythontrain.py12训练pnet将目录cd到preprocess上,pythongen_hard_example.py12生成三种rnet数据,pythongen_landmark_aug.py24生成rnet的landmark数据,pythongen_tfrecords.py24生成tfrecords文件将目录cd到train上pythontrain.py24训练rnet将目录cd到preprocess上,pythongen_hard_example.py24生成三种onet数据,pythongen_landmark_aug.py48生成onet的landmark数据,pythongen_tfrecords.py48生成tfrecords文件将目录cd到train上pythontrain.py48训练onet3.2构建APP实现摄像头预览如上图所示,我将摄像头预览分为以下七个主要步骤。调用Camera的open(intCameraId)方法打开摄像头。手机的摄像头照常来说分为前后摄像头,对应的CameraId分别为android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT和android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK,由于本次毕业设计为自拍式的美颜相机,因此将CameraId默认设置为前置摄像头,即android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT。调用android.hardware.Camera.open(CameraId),其中CameraId即上文所提到的前置摄像头ID,并判断是否调用成功,返回参数为boolean。这是由于有时候手机权限没有授予的原因或者摄像头出现损坏等原因,导致无法正常开启,以便对之后的情况进行相应的处理。如果返回的boolean值为true就正常进行摄像头预览下一步步骤,如果返回的boolean值为false,则表明无法正常打开摄像头,就会显示权限没授予或者摄像头损坏。调用Camera的getParameters()得到该摄像头的参数。这一步主要是为了获取该摄像头的参数,调用Camera.getParameters()会得到android.hardware.Camera.Parameters对象,为之后使用Camera.Parameters对象进行参数设置。调用Camera.Parameters对象对参数进行设置。得到android.hardware.Camera.Parameters对象,便可对参数进行设置。调用Parameters.setFocusMode(Stringvalue)设置聚焦模式,对应的value有六种:“auto”-自动,“infinity”-无穷远,“macro”-微距,“Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE”-连续对焦,以及“fixed”-固定焦距。由于本次毕业设计使用的是摄像头预览,因此采用的是连续对焦,增加视频流的清晰度,使预览画面辨识度更高。Parameters.setPreviewSize(intwidth,intheight)设置预览大小的宽和高,有每个设备可以允许使用的显示大小不同,再加上与显示Surface的大小有关,所以需要进行适配,首先使用Parameters.getSupportedPreviewSizes()来获取Camera所支持的大小,一般得到一系列的Camera.Size,我将其保存在一个链表中,即List<android.hardware.Camera.Size>中,由于对分辨率没什么强制性要求,通常就直接取第一个分辨率,使用List.get(inti)来获取大小,i为链表中的位置,从零开始。使用Size.width和Size.height来获取该大小尺寸的宽和长,将其输入到上文提到的函数中来设置预览的大小。调用Camera的setDisplayOrientation(intvar1),进行预览角度。如上图所示,Camera的图像数据来源于摄像头的,而这个摄像头在被固定到手机上后会被默认选择一个方向,一般为手机向左横放。又因为手机的屏幕可以进行任意角度旋转,这样就会导致人眼所看到的图像与手机摄像头显示的头像就会产生一定的误差,用户就不一定看到正确的预览界面,也就是人眼所见与你的预览界面不一致,因此需要根据手机屏幕所在的方向来设置正确的预览方向。对于横屏的应用软件,其方向与手机系统摄像头默认的方向一致,因此不用做额外的修改,但对于竖屏应用软件来说,则需要进行方向修正,来确保方向一致,且前后摄像头也不一样,后置摄像头只需要修改一下预览方向,而前置摄像头显示的是镜像图像需要进行水平翻转,而不需要修改方向。因此创建一个函数专门为这个调整预览方向做处理,首先通过Camera自带的函数activity.getWindowManager().getDefaultDisplay().getRotation()获取手机系统现在的方向,通过Camera.getCameraInfo(cameraId,info)获取摄像头参数信息,当判断摄像头朝向为前置摄像头时,取360度-摄像头方向的角度-手机系统当前的角度;如果是摄像头朝向是后置摄像头,则取360度+摄像头方向角度+手机系统当前的角度。调用Camera的setParameters(Camera.Parametersparams),并将通过上面几个步骤设置好的Parameters对象作为输入参数传入,这样就可完成了对摄像头的一些关键的参数设置。activity_main.xml中编写用来预览的SurfaceView以及在AndroidManifest.xml中添加摄像头权限及聚焦权限,例如:<uses-permissionandroid:name="android.permission.CAMERA"/><uses-featureandroid:name="android.hardware.camera"/><uses-featureandroid:name="android.hardware.camera.autofocus"/>6、调用Camera的setPreviewTexture(SurfaceTexturevar1)来设置预览的窗口,函数内的参数为之前在activity_main.xml中编写用来预览的SurfaceView,并对其取一个ID名,调用findViewById(R.id.xxxxx),xxxxx即取得ID名,便可获取到用来预览的SurfaceView,最后调用Camerade的startPreview()函数开启预览,预览的启动过程全部完成了。7、在应用程序终止时,要调用Camera的stopPreview()函数停止预览,并且使用Camera.release()来释放资源,避免出现摄像头等资源没有被使用却仍在占用的情况,会导致资源浪费。3.3载入模型修改build.gradle(Module:app)内容。这一步是为了载入tensorflow模块,以便编译器能够识别。以Android的形式显示文件内容,在GradleScripts目录下就会找到build.gradle(Module:app),双击打开,在其末尾空白处,另起一行,添加以下内容:allprojects{repositories{jcenter()}}dependencies{compile'org.tensorflow:tensorflow-android:+'}测试一下,新建一个类,在里面添加属性,如下:TensorFlowInferenceInterfaceten;看看是否会出现错误,如果没有,就说明tensorflow模块已经载入成功,系统可以成功识别;如果不能,就说明模块没有载入,可以去官网找找资看看是哪一步出错,还是环境没配置好。在main文件夹下创建assets文件夹,将模型文件导入。在Project显示形式下,在app.src.main文件夹下右键,在目录中选择new->Directory,取名为assets,将之前训练好的模型,用快捷键Ctrl+C,Ctrl+V复制粘贴进来就可以了。创建调用MTCNN的类,使系统能够正确调用该模型。ⅰ创建MTCNN的有参构造函数MTCNN(AssetManageram)有参构造函数主要两个作用:获取AssetManager和加载模型。Android应用程序的资源可以分为两大类:assets和res,assets类资源可以以任何的方式进行组织,而这些文件最后会被原封不动的地打包在APK文件中。由于我们将MTCNN模型文件放入assets文件夹下,如果我们需要在应用程序中访问或者调用这些文件,就需要获取Android资源管理框架,即AssetManager来访问它。调用TensorFlowInferenceInterface(AssetManagerassetManager,Stringmodel),初始化TensorFlowInferenceInterface对象,根据指定的model创建一个本地的Tensorflowsession。ⅱ创建函数detectFaces(Bitmapbitmap,intminFaceSize),用来调用模型识别人脸,并输出人脸坐标链表首先输入参数有两个:bitmap要处理的图片,minFaceSize最小的人脸像素值调用PNet函数,获取经过PNet神经网络筛选出来的疑似人脸区域链表Vector<Box>boxes。调用square_limit对输出的疑似人脸区域进行微调,使人脸区域保持为原先区域的最大正方形。调用RNet函数,将经过PNet过滤后的疑似人脸区域链表代入,输出经过RNet神经网络筛选出来的更加准确的人脸区域链表Vector<Box>boxes。再次调用square_limit进行疑似人脸区域调整,微调后为原先最大正方形最后调用ONet函数,将经过RNet过滤后的疑似人脸区域链表代入,输出最终的人脸区域链表。ⅲ创建PNet(Bitmapbitmap,intminFaceSize)函数,输入为bitmap要处理的图片,minFaceSize最小的人脸像素值,输出为疑似人脸区域的坐标链表。建立一个while循环,只有当minFaceSize>bitmap长和宽中最小值,跳出循环,每循环一次,minFaceSize=minFaceSize/0.7。在循环中,调用bitmapResize函数,对输入图像进行Resize,输出放大后的图像。调用PNetForward函数,运行PNet神经网络,使用inferenceInterface.feed输入参数,inferenceInterface.run运行,inferenceInterface.fetch取出结果,最后输出两个float二维数组。调用generateBoxes对输出的二维数组进行数据解析,将结果保存至类型为Box的链表中。调用非极大值抑制函数,抑制值为0.7,去除不符合要求的Box。调用边框区域回归函数,进行区域坐标化整,将数值一律化为整型。最后输出处理完后的疑似人脸区域的坐标链表。ⅳ创建RNet(Bitmapbitmap,Vector<Box>boxes)函数输入为bitmap要处理的图片,boxes是经过PNet神经网络辨识后的疑似人脸区域坐标链表,输出为疑似人脸区域的坐标链表。调用crop_and_resize截取boxes中指定的矩形框,并将其Resize到24*24大小,将处理后的数据存入浮点型的一维数组中。调用RNetForward函数,运行RNet神经网络,使用inferenceInterface.feed输入参数,inferenceInterface.run运行,inferenceInterface.fetch取出结果,得到类型为Box的链表。用非极大值抑制函数,抑制值为0.7,去除不符合要求的Box。调用边框区域回归函数,进行区域坐标化整,将数值一律化为整型。最后输出处理完后的疑似人脸区域的坐标链表。ⅵ创建ONet(Bitmapbitmap,Vector<Box>boxes)函数输入为bitmap要处理的图片,boxes是经过RNet神经网络辨识后的疑似人脸区域坐标链表,输出为疑似人脸区域的坐标链表。调用crop_and_resize截取boxes中指定的矩形框,并将其Resize到48*48大小,将处理后的数据存入浮点型的一维数组中。调用RNetForward函数,运行RNet神经网络,使用inferenceInterface.feed输入参数,inferenceInterface.run运行,inferenceInterface.fetch取出结果,得到类型为Box的链表。用非极大值抑制函数,抑制值为0.7,去除不符合要求的Box。调用边框区域回归函数,进行区域坐标化整,将数值一律化为整型。最后输出处理完后的疑似人脸区域的坐标链表。ⅶ创建nms(Vector<Box>boxes,floatthreshold,Stringmethod)函数。非极大值抑制函数,输入为疑似人脸区域坐标链表,抑制值及方法标志,输出为疑似人脸区域的坐标链表。主要对比思想就是两两对比,通过双重FOR循环进行对比,计算各自的面积以及重复的面积,计算IOU的公式为:IOU=甲乙重复的面积/(甲面积+乙面积-甲乙重复面积)如果IOU比抑制值小的,则对其进行删除;如果IOU比抑制值大的,则留下。ⅷ创建BoundingBoxReggression(Vector<Box>boxes)函数。边缘回归函数,输入为疑似人脸区域坐标链表,输出为疑似人脸区域坐标链表。使用FOR循环进行提取单个人脸区域坐标,将左上坐标的横坐标与右下坐标的横坐标相减计算宽,将左下坐标的纵坐标与右上坐标的纵坐标相减计算高。对其进行整型化处理。3.4实现菜单1、创建menu,在Android显示中,选择res右键,选择NewResourceDirectory,类型选择menu,就可以创建menu,在menu.xml中编辑菜单栏,例如:<itemandroid:id="@+id/menu_original"android:title="原图像"/>调用onCreateOptionsMenu函数,每次Activity一创建就会执行,一般只执行一次,创建并保留Menu的实例。编辑菜单点击事件onOptionsItemSelected,当每次menu菜单项被点击时,该方法就会被执行一次,。使用switch根据MenuItem的不同进入不同的case响应事件。3.5实现渲染当点击菜单对应的选项,触发onOptionsItemSelected,通过Switch设置相应的滤镜类型值,传给渲染类CameraRenderer,CameraRenderer创建新的FilterEngine,FilterEngine创建新的Progress并根据传来的值选择相应片着色器,将顶点着色器和片着色器附在Progress上,链接Progress并告诉OpenGLES使用此program。3.6实现美颜3.6.1美白使用texture2D获取自身的rgba的四维向量值,将值乘以(1+美白进度条的进度值/200),使得亮度提升,达到美白效果。3.6.2磨皮使用texture2D获取自身的rgba的四维向量值,首先取出像素的green通道值,对其进行高反差保留,进行强光处理处理,计算像素灰度值,将灰度值进行次方,将原图像加上高反差保留图像乘次方值。3,6.3红润texture2D获取自身的rgba的四维向量值,将值的平方乘3-值的三次方乘2,由于r的值处于0~1之间,如图所示会使小于0.5的值变小,增大0.5的值,从而使得图像变红润。3.6.4实现Android拖动条(SeekBar)在activity_main.xml布局中定义拖动条,通过findViewById获取SeekBar,设置setOnSeekBarChangeListener监听拖动条,onProgressChanged调用getProgress传递拖动条的值给CameraRenderer,CameraRenderer将值传递给片着色器。3.7实现滤镜3.7.1模糊滤镜texture2D获取自己周围九个点的rgba的四维向量值,与0.0950.1180.0950.1180.1480.1180.0950.1180.095进行卷积,将加权和的四维向量值赋给gl_FragColor。3.7.2黑白滤镜texture2D获取自身的rgba的四维向量值,将gl_FragColor的rgb值赋值为0.3*r+0.59*g+0.11*b。3.7.3四分滤镜texture2D获取自身的rgba的四维向量值,将其缩小为原来的四分之一,再进行对应的依次复制到其他剩余的地方。如下图,先将整副图像缩小至原来的四分之一即A区域,之后依次复制至B、C、D三个区域。ABCD结论我将美颜分为三部分:美白、磨皮和红润,其中磨皮算法相对于其他来讲,应该是比较难的了,我第一次实现磨皮的想法就是直接作高斯模糊然后锐化,效果一般且锐化效果明显边缘突出导致整个画面不自然。之后,我就去网上查找相关资料,发现大部分磨皮算法都用到了双边滤波,由于其模糊保留边缘,因此磨皮效果好。不过我尝试了一下,由于处理时间过长,250ms一帧,导致画面很卡,实时帧率在4-5之间,无法满足30fps的要求,不过可以个人感觉用来处理照片还是不错的。我就想能不能改进一下,经过尝试发现还不如原来的,去网上捜了下,发现有个双边滤波的改进版快速双边滤波,解决了处理时间长的问题,不过没看懂就没用了。最后尝试的是高反差保留,这个算法最大的特点用与原图像减去高斯模糊和强光处理的图像得到的只留下边缘信息,且满足30fps,美颜效果不错,就是去痘效果不太明显。经过查找资料,了解到green中含有信息较多,对green信息了个次方处理,会不会去痘效果好些,尝试了一下,果然还不错,就是感觉拉拖动条的时候变化不明显。通过双边滤波处理实现美颜效果明显,但是每一帧处理时间太长,达到250ms一帧,无法实现实时美颜,因此我查询网上资料,发现有一种快速双边滤波,是在双边滤波的基础上进行的改进,克服了双边滤波处理时间长的缺点。致谢主要参考文献张志强,王万玉.一种改进的双边滤波算法[J].中国图象图形学报,2019,14(3):443-447.ZhangK,ZhangZ,LiZ,etal.JointFaceDetectionandAlignmentUsingMultitaskCascadedConvolutionalNetworks[J].IEEESignalProcessingLetters,2016,23(10):1499-1503.附录1、标签处理函数deftransformTxt(original_txt_path,final_txt_path):'''对TXT文件中label信息进行处理,留下文件路径和所有的人脸box:paramoriginal_txt_path:原始txt文件地址:paramfinal_txt_path:处理后txt文件地址:return:bool值True或False'''#以写入的方式打开文件w_file=open(final_txt_path,'w')#以只读的方式打开txt文件withopen(original_txt_path,'r')asr_file:lines=r_file.readlines()path_flag=Falseface_num_flag=Falseforlineintqdm(lines):#去除头尾空格line=line.strip()#判断是否是文件路径名if'jpg'inline:path_flag=Trueseek_point=w_file.tell()w_file.write(str(line)+str(''))continue#获取人脸数量ifpath_flag==True:path_flag=Falseface_sum=lineifint(face_sum)==0:face_num_flag=Truecontinue#处理人脸数量为零的图片ifface_num_flag==True:#删除该行w_file.seek(seek_point,0)face_num_flag=Falsecontinue#判断是否是坐标x,y,w,hifint(face_sum)>0:face_sum=int(face_sum)-1result=line.split('')foriinrange(4):ifi<2:w_file.write(str(result[i]))else:#保留两位小数sum=float(result[i-2])+float(result[i])w_file.write(str(sum))w_file.write('')ifint(face_sum)==0:w_file.write('\n')continuew_file.close()returnTrue2、IOU计算函数defIOU(box,boxes):'''裁剪的box和图片所有人脸box的iou值:parambox:裁剪的box,当box维度为4时表示box左上右下坐标,维度为5时,最后一维为box的置信度:paramboxes:图片所有人脸box,[n,4]:return:iou值,[n,]'''#计算截取的box面积box_area=(box[2]-box[0]+1)*(box[3]-box[1]+1)#boxes面积,[n,](第3列-第1列+1)*(第4列-第2列+1)boxes_area=(boxes[:,2]-boxes[:,0]+1)*(boxes[:,3]-boxes[:,1]+1)#计算重叠部分左上右下坐标左上取最大值,右下取最小值x1=np.maximum(box[0],boxes[:,0])y1=np.maximum(box[1],boxes[:,1])x2=np.minimum(box[2],boxes[:,2])y2=np.minimum(box[3],boxes[:,3])#重叠部分长宽width=n

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论