时间:2024-05-04
赖奕然 林泽浩 伍绍锋 唐一星
摘要:自2006年开始,深度学习算法开始出现,人工智能技术获得飞速发展,人工智能的春天悄然来临,一时间各大深度学习平台宛如雨后春笋般涌现,由百度开发的PaddlePaddle深度学习平台就是其中的佼佼者。为了实现给人像实时添加趣味贴图的功能,此项目通过使用PaddlePaddle框架的预训练集PaddleHub来提取图像的关键点数据,再使用PaddlePaddle库、OpenCV库和Python语言得到的关键点分类、选择,最后与经过预处理的贴纸匹配,即可得到贴纸人脸趣味图像。实验结果表明:本方法可以很好地对人脸图像进行识别并将贴图贴至指定位置,具有极高的准确率。
关键词:人工智能;深度学习;PaddlePaddle;人脸识别;图像识别
中图分类号:TP391 文献标识码:A
文章编号:1009-3044(2022)25-0073-03
开放科学(资源服务) 标识码(OSID) :
1 概述
图像识别是人工智能的一个重要领域,其目的是让计算机代替人类去处理大量的视觉信息。随着时代的发展,人类自身识别能力已经满足不了需求,需要计算机的图像识别技术帮助实现一些人类无法完成的工作[1]。
本项目基于PaddlePaddle平台,通过调用 PaddleHub 的接口实现人脸边框的检测,为了方便使用,首先对检测到的人脸图像关键点进行分类,从分类好的关键点中取出左眉毛最左的点和右眉毛最右的点来计算角度,根据计算得到的角度来把效果贴纸旋转至与人脸图像匹配的角度,最后将参考点与人脸对应的一个点进行融合得到最终结果。
2 技术介绍与主要流程
2.1 技术介绍
本项目采用深度学习框架飞桨(PaddlePaddle) 进行项目实现。百度从2012年开始研发具备完全自主知识产权的深度学习框架飞桨,并建成了国内唯一的集深度学习训练和预测框架、模型库、工具组件等为一体的开源深度学习平台[2]。同时也是国内唯一功能完备的端到端开源深度学习平台,拥有兼顾灵活性和高性能的开发机制、工业级应用效果的模型、超大规模并行深度学习能力、推理引擎一体化设计以及系统化服务支持的五大优势[3]。
PaddleHub是飞桨生态下的预训练模型的管理工具,PaddleHub作为模型管理和迁移学习工具,采用了飞桨领先的核心框架,精选效果优秀的算法快速地实现模型的预测、升级等功能。到目前为止,PaddleHub的预训练模型覆盖了用于图像分类、图像生成、关键点检测等主流模型[4]。
开源计算机视觉库(OpenCV:Open Source Computer Vision Library)实现了计算机视觉相关的许多算法,同时也实现了图像处理很多常见的通用算法。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、Matlab等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法[5-6]。
功能框架图如图1所示。
2.2 具体步骤
2.2.1 获取图像和图片预处理
通过Python语言获取需要检测的目标图像。再使用OpenCV库,对图像进行预处理,例如颜色通道转换、切片、分离颜色通道,中值滤波处理等操作。
2.2.2 检测人脸并叠加目标贴纸
接下来是人脸关键点检测,它在人脸识别和分析领域中是十分关键的一步,也是绝大部分人脸相关问题的前提和突破口。
导入PaddleHub模型库中的face_landmark_localization模型和ultra_light_fast_generic_face_detector_1mb_320模型进行图像的人脸检测,返回人脸云点阵图和人脸面框识别结果。人脸云点阵图如图2所示。
再使用OpenCV库,将目标贴纸图像导入,并把人脸云点阵图区分为几个部分,比如鼻、眼睛、嘴巴、额头等,以便于后续的位置计算。
2.2.3 旋转贴纸
确定好要放置的人脸图像,计算两点之间的角度数据。通过计算两标记点的XY轴的差值,再用角度ATAN函数计算两点之间的角度,以下计算两点之间角度函数以方便后续计算参考点的位置。确定了位置数据后,将贴纸图像进行一定角度的旋转,并返回旋转图像和相应的旋转矩阵。
2.2.4 贴纸位置
根据贴纸上一个点作为参考点,通过计算两眼标记的中心点,确定眼镜照片的中心点。为了计算两眼中间点之间的长度,将两眼坐标带入求范数函数(np.Linalg.norm) ,求出两眼之间的长度,再用旋转矩阵计算旋转之后相对应的中心位置。
2.2.5 放置贴纸
根据人脸的宽度与贴纸图像进行尺寸的核对以及修改,同时计算修改尺寸之后的图像相对应的位置信息数据。调整旋转矩阵用于之后的平移操作,并将眼镜图片和仿射变化矩阵数组和调整后的图片高度及宽度带入cv2.warpAffine函数进行仿射变化,最后得到旋转后图像。
2.2.6 显示结果
将获取到的参考点与人脸需要贴近的部分对应的坐标点进行融合,导入人脸部图片和眼镜图片,并且设立数组来存放眼镜图片的各项具体信息。将得到的坐標系数带入计算眼镜左边位置坐标的函数中,将人脸图片和眼镜图片以及由上述操作中得到的位置坐标代入将贴纸图片贴入图片的函数中,将人脸图片导入,从而获取最终的图像结果。效果图如图3、图4所示。
3 功能详细设计
3.1 面部关键点和人脸面框识别
主要基于PaddlePaddle框架的PaddleHub模型实现面部关键点点阵图的绘制和人脸面框的识别。首先导入依赖库,定义两个全局变量,Labels 用于表示人脸的每个部分,Colors用于对不同的关键点进行颜色标记;通过基于PaddlePaddle开发的预训练模型管理工具PaddleHub的face_landmark_localization模型,可以快速提供人脸部的68个关键点(人脸轮廓17个点,左、右眉毛各5个点,左、右眼睛各6个点,鼻子9个点,嘴巴20个点) ,并返回68个人脸关键点数据,再通过自定义函数调用Paddle Hub的ultra_light_fast_generic_face_detector_1mb_320模型,实现人脸编辑框的检测,返回人脸框左上角的点坐标和边框的宽和高;为了方便使用,将68个人脸关键点分成了人脸的各个部分。部分代码如下所示:
module=hub.Module(name="face_landmark_localization")
result=module.keypoint_detection(images=[src_img])
face_detector=hub.Module(name="ultra_light_fast_generic_face_detector_1mb_320")
result = face_detector.face_detection(images=[img])
3.2 图片的预处理
主要使用OpenCV库对图片进行预处理。第一步是颜色通道的转换,使用cv2.cvtColor将BRG转换成BGRA,以便于后续图片处理;然后进行切片处理,以保证贴图和原图片尺寸大小一致;接下来是对贴图的处理。将贴图的4个颜色通道分离,分为B、G、R、A四个通道,再使用cv2.medianBlur对贴图的A通道进行中值滤波处理,以尽可能消除椒盐噪点的影响,并使之作为cv2.bitwise中的掩膜。部分代码如下所示:
if bg_img.shape[2] == 3:
bg_img = cv2.cvtColor(bg_img, cv2.COLOR_BGR2BGRA)
b, g, r, a = cv2.split(img_to_overlay_t)
mask = cv2.medianBlur(a, 5)
h, w, _ = img_to_overlay_t.shape
roi = bg_img[int(y - h / 2):int(y + h / 2), int(x - w / 2):int(x + w / 2)]
3.3 原图片和贴图的叠加
原图片和贴图的叠加,主要也是使用OpenCV库进行操作。第一步先利用cv2.bitwise_and将人脸和贴图部分提取出来,再使用cv2.add将两张处理过后的图片叠加在一起,最后合成图片的颜色通道从BGRA转换为BRG。部分代码如下所示:
img1_bg=cv2.bitwise_and(roi.copy(),roi.copy(),mask=cv2.bitwise_not(mask))
img2_fg=cv2.bitwise_and(img_to_overlay_t,img_to_overlay_t,mask=mask)
bg_img[int(y - h / 2):int(y + h / 2), int(x - w / 2):int(x + w / 2)]= cv2.add(img1_bg, img2_fg)
bg_img = cv2.cvtColor(bg_img, cv2.COLOR_BGRA2BGR)
3.4 计算两个标记点的角度
编写函数,函数功能是计算两个标记点的位置和角度,以便对应贴纸的放置位置和旋转角度,为后期做贴纸放置做准备。
通过计算两标记点的XY轴的差值,再用角度atan函数计算两点之间的角度,以下为计算两点之间角度函数:
Def angle_between(p1,p2) :
X-diff=p2[0]-p1[0]
Y-diff=p2[0]-p1[0]
Return degrees(atan2(y_diff,x_diff)
3.5 将贴纸图片贴入图片中
编写函数,函数功能是将贴纸图片通过函数进行偏转,并贴到相应位置;函数需要的参数分别是左眼中心点坐标(eye_left_center) 和右眼中心點坐标(eye_right_center) 以及眼镜图片(glasses) 的各项数据包括眼镜图片的高度(glasses-h) 眼镜图片的宽度(glasses-w) 。通过计算两眼标记的中心点,确定眼镜照片的中心点(glasses-center) 。为了计算两眼中间点之间的长度,将两眼坐标带入求范数函数(np.Linalg.norm) 求出两眼之间的长度,在此基础上乘以2,得到眼镜照片的大小(glasses-size) 。
现将左右眼中心点坐标代入上述计算两点坐标角度的函数中(angle-between) ,得到两眼之间的角度(angle) ,再对眼镜图片的宽度和高度进行切片操作。用高度和宽度确定眼镜图片的中心点(glasses-c) ,再通过getRotationMatrix2D函数获得仿射变化矩阵(M) ,最后通过中心点和两眼之间的角度,得出角度的cos和sin数值,再通过将图片的高度和宽度与偏转角度相乘,得出偏转之后的图片高度(nH) 和宽度(nW) 。
再调整旋转矩阵用于之后的平移操作,并将眼镜图片和仿射变化矩阵数组,和调整后的图片高度及宽度带入cv2.warpAffine函数进行仿射变化,得到旋转后的眼镜图片(rotated-glasses) ,最后带入上述融合两张图片的函数图像函数(overlay-transparent) 中,并输入融合后的图片(image) 。
3.6 计算眼镜位置坐标
编写函数,函数功能是计算眼镜的坐标位置,用于计算出贴纸的尺寸和位置,为融合两张图片作准备,以下是函数的代码:
def get_eye_center_point(landmarks, idx1, idx2):
center_x = (landmarks[idx1][0] + landmarks[idx2][0]) // 2
center_y = (landmarks[idx1][1] + landmarks[idx2][1]) // 2
return (center_x, center_y)
3.7 主函数
首先是要导入人脸部图片和眼镜图片,并且设立数组来存放眼镜图片的各项具体信息。将人脸图片导入。导入预处理函数对图片进行预处理,并代入result,得出识别标记点的函数如下:
result = module.keypoint_detection(images=[image])
landmarks = result[0]['data'][0]
将得到的坐标系数带入,计算眼镜左边位置坐标的函数(get_eye_enter_point)中:eye_left_point=get_eye_ center_point(landmarks, 36, 39)
eye_right_point = get_eye_center_point(landmarks, 42, 45)
将人脸图片(image) 、眼镜图片(glasses) 以及由上述操作中得到的位置坐标代入,将贴纸图片贴入图片的函数中:
image=wear_glasses(image, glasses, eye_left_point, eye_right_point)
最后,将图片进行优化,并最终展示生成的图片:
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
im = plt.imshow(image, animated=True)
4 总结与展望
为了确保对目标图形对象的准确识别,本项目在PaddlePaddle平台提供的运行库上进行了调整,提高了识别精准度,并利用了OpenCV基础库来完善与实现人脸图像识别,在经过了反复测试后,拥有了较高的准确率和有效性,但在一些模糊的人脸照片或非全脸照片时,鲁棒性有待提高,因此有待于进一步研究,提高其鲁棒性。
參考文献:
[1] 季秀怡.浅析人工智能中的图像识别技术[J].电脑知识与技术,2016,12(14):147-148.
[2] 马艳军,于佃海,吴甜,等.飞桨:源于产业实践的开源深度学习平台[J].数据与计算发展前沿,2019,1(5):105-115.
[3] 袁颖,李论,杨英仓.基于FPN-SE-Capsule网络的指纹图像识别算法[J].工业控制计算机,2021,34(1):45-47,50.
[4] 唐心雨,陈霜霜,路鹏,等.基于PaddleHub的人脸口罩识别系统[J].海南师范大学学报(自然科学版),2021,34(2):177-184
[5] 罗怀荣.基于Web3D的多平台温室监测系统设计[D].重庆:西南大学,2017.
[6] 王浩,许志闻,谢坤,等.基于OpenCV的双目测距系统[J].吉林大学学报(信息科学版),2014,32(2):188-194.
【通联编辑:唐一东】
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!