赞
踩
图像视频处理在计算机视觉中是一个基本但具有挑战性的任务。它旨在提供详细的人脸关键点定位,相当于为每个人脸进行关键点描点。该技术目前被广泛应用于短视频媒体平台、直播等系统领域。以我们选用的“人脸关键点识别”数据集为例,该项目的挑战在于:
不同的场景会有不同的光照等因素,光照的来 源方向、光照强度的不同都影响人脸图像的灰度布局。
定位出人脸面部的关键区域位置,包括眉毛、眼睛、鼻子、嘴巴、脸部轮廓等和人脸检测类似,由于受到姿态和遮挡等因素的影响。
要实现对视频和图像中的人脸的追踪并分析面部表情,来检测畸形面部体征以进行我们图像视频处理。
·paddlepaddle >= 2.0.0rc1
·Python >= 3.7
·dlib库的安装(适配于python版本,本文提供3.8版本Python的dlib安装文件)
强烈建议您安装/使用 GPU 版本的 PaddlePaddle。因为人脸关键点定位模型开销很大,当模型运行在 CPU 时可能会出现内存不足。更详细的安装教程请参考 PaddlePaddle 官网
1.首先下载文件dlib-19.19.0-cp38-cp38-win_amd64.whl
该文件在文件浏览器下,可以直接下载。
2.将下载的whl文件放到任意的路径下,然后通过命令行进入到该目录下,
然后运行代码:
pip install dlib-19.19.0-cp38-cp38-win_amd64.whl
之后回车安装即可。
项目部分代码在 dingwei.zip 文件中,数据集在 data.zip 文件中,解压到合适路径即可使用。除了压缩包文件中的程序,也可以在在aistudio项目中可以直接查阅作品中对于帽子和嘴巴特效定位处理的代码:
#嘴巴特效: import cv2 # 图像处理的opencv库 import argparse # 加载解析模块 import os def hat_face(opt): # 加载dlib的人脸检测模型 detector = dlib.get_frontal_face_detector() # 使用opencv中的imread函数,读取需要添加特效的图片 landmark_predictor = dlib.shape_predictor(opt.landmarks_model_path) # 使用opencv中的imread函数,读取嘴巴的图片 img_hat = cv2.imread(opt.hat_path) # img_hat = img_hat[:] # 对图片进行dlib人脸检测,得到检测后的人脸框信息faceRects # faceRects = detector(img, 0) # 图片中可能存在多张人脸,依次遍历输出每张人脸的位置信息,并在特定位置,添加嘴巴特效 cap = cv2.VideoCapture(opt.video_path) force= cv2.VideoWriter_fourcc("X","V","I","D") out1 = cv2.VideoWriter("output.avi",force,20,(640,480)) frame_id = 0 while cap.isOpened(): try: # 因为视频采集,每秒可能会采集N帧图片,因此使用read函数,逐帧读取图片 # ret 返回True或Fasle,表示是否读取到图片 # frame 返回读取的图片信息 ret, frame = cap.read() # 如果ok为false,则采集结束 if not ret: # 打印输出,提示信息 print("Camera cap over!") continue # frame_id加1,便于跳帧 frame_id += 1 if not int(frame_id) % 2 == 0: continue faceRects = detector(frame) if len(faceRects) > 0: for box_info in faceRects: # dlib检测出的人脸位置信息,为rectangle类型,所以可以通过left()、top()、right()、bottom()提取人脸框左上角的x0,y0,右下角的x1,y1。 x0, y0, width_face, height_face = box_info.left(), box_info.top(), box_info.right() - box_info.left(), box_info.bottom() - box_info.top() landmarks = landmark_predictor(frame, box_info) # 获得嘴巴图片的高height_hat,宽width_hat,便于后面控制嘴巴显示的大小 height_hat, width_hat = img_hat.shape[0], img_hat.shape[1] # 将嘴巴的高度变成,适合检测到的脸型的大小 imgComposeSizeH = int(height_hat / width_hat * width_face) # 因为嘴巴在脸部上方,当脸部靠近视频顶部,为了保证嘴巴能显示出来,嘴巴的高度默认为脸部到视频上方的距离 if imgComposeSizeH > (y0 + 220): imgComposeSizeH = (y0 + 220) # 将嘴巴的图片归一化到适合的宽和高大小,宽度为人脸的宽度,高度为上面调整后的嘴巴高度 imgComposeSize = cv2.resize(img_hat, (width_face, imgComposeSizeH), interpolation=cv2.INTER_NEAREST) # 为了实现在人脸上方的额头,添加嘴巴特效,只需要将嘴巴贴到额头处即可 # 注意:y0是人脸检测框左上方顶点的y坐标,y0-20,则差不多定位到额头处,再减去imgComposeSizeH,调整后嘴巴的高度 # 即从这个位置开始贴合嘴巴,可以实现人脸嘴巴特效 top = (y0 + 220 - imgComposeSizeH ) # 当人脸太靠近图片上方,通过前一行的计算,有可能为负数,所以当出现这样的情况时,top设置为0 if top <= 0: top = 0 # 获得调整尺寸后,嘴巴新的高height_hat_new,新的宽width_hat_new height_hat_new, width_hat_new = imgComposeSize.shape[0], imgComposeSize.shape[1] small_img_hat = frame[top:top + height_hat_new, x0:x0 + width_hat_new] # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("small_img_hat.jpg",small_img_hat) # 将嘴巴图像,从RGB彩色图像转换为灰度图像 small_img_hat_gray = cv2.cvtColor(imgComposeSize, cv2.COLOR_RGB2GRAY) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("small_img_hat_gray.jpg", small_img_hat_gray) # 阈值化处理,将10<像素<255区间的图像抠出来 # 因为背景为黑色,所以阈值设置10到255,即可将嘴巴区域提取出来 ret, mask_hat = cv2.threshold(small_img_hat_gray, 10, 255, cv2.THRESH_BINARY) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("mask_hat.jpg", mask_hat) # 使用取反操作,将嘴巴的图像从黑色0变为白色255,将白色255变成黑色0 mask_hat_inv = cv2.bitwise_not(mask_hat) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("mask_hat_inv.jpg", mask_hat_inv) # 使用按位与操作,将抠出的嘴巴区域和取反后的嘴巴图像相加 img1_bg = cv2.bitwise_and(small_img_hat, small_img_hat, mask=mask_hat_inv) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("img1_bg.jpg", img1_bg) # 使用按位与操作,将像素值在[10,255]之间的帽子RGB区域抠取出来 img2_fg = cv2.bitwise_and(imgComposeSize, imgComposeSize, mask=mask_hat) dst = cv2.add(img1_bg, img2_fg) # img_bg = cv2.bitwise_and(roi_face, roi_face, mask=mask_eyeglass_inv) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("dst.jpg", dst) # 将带了嘴巴的局部区域,贴合到原始图像上 frame[top:top + height_hat_new, x0:x0 + width_hat_new] = dst out1.write(frame) img = cv2.resize(frame, (800, 600)) # 显示图片 cv2.imshow("image", img) # 显示图片停顿的时间,如果是0,则一直显示。如果是100,则显示100ms if cv2.waitKey(1) & 0xFF == ord('q'): break # 按‘q’退出 except:pass ### 函数主入口 # if __name__ == '__main__': # 新建一个解析器 def zuibab5(): parser = argparse.ArgumentParser() # 为解析器添加选项,比如image_path,添加图片地址,可以更换其他图片尝试。(在default后面,添加需要读取的图片路径) # 注意:不同的图片,宽高大小可能不同,大家可以根据自己的图片比例,调试前面的的cv2.resize中的数值,修改显示窗口的大小。 parser.add_argument('--video_path', default=0, help='path of cap video') # apath = os.path.abspath("mao1.png") # print(apath) # 为解析器添加选项,比如hat_path,添加嘴巴图片地址。(在default后面,添加需要读取的嘴巴图片路径) parser.add_argument('--hat_path', default="./image/zui5.1.png", help='path of hat image') parser.add_argument('--landmarks_model_path', default="shape_predictor_68_face_landmarks.dat", help='path of model') # 解析选项的参数 opt = parser.parse_args() # 调用hat_face函数,对人脸进行检测,添加嘴巴特效 hat_face(opt)
#帽子特效: import cv2 # 图像处理的opencv库 import argparse # 加载解析模块 import os def hat_face(opt): # 加载dlib的人脸检测模型 detector = dlib.get_frontal_face_detector() # 使用opencv中的imread函数,读取需要添加特效的图片 landmark_predictor = dlib.shape_predictor(opt.landmarks_model_path) # 使用opencv中的imread函数,读取兔子帽子的图片 img_hat = cv2.imread(opt.hat_path) # img_hat = img_hat[:] # 对图片进行dlib人脸检测,得到检测后的人脸框信息faceRects # faceRects = detector(img, 0) # 图片中可能存在多张人脸,依次遍历输出每张人脸的位置信息,并在特定位置,添加兔子帽子特效 cap = cv2.VideoCapture(opt.video_path) frame_id = 0 while cap.isOpened(): # 因为视频采集,每秒可能会采集N帧图片,因此使用read函数,逐帧读取图片 # ret 返回True或Fasle,表示是否读取到图片 # frame 返回读取的图片信息 ret, frame = cap.read() # 如果ok为false,则采集结束 if not ret: # 打印输出,提示信息 print("Camera cap over!") continue # frame_id加1,便于跳帧 frame_id += 1 if not int(frame_id) % 2 == 0: continue faceRects = detector(frame) if len(faceRects) > 0: for box_info in faceRects: # dlib检测出的人脸位置信息,为rectangle类型,所以可以通过left()、top()、right()、bottom()提取人脸框左上角的x0,y0,右下角的x1,y1。 x0, y0, width_face, height_face = box_info.left(), box_info.top(), box_info.right() - box_info.left(), box_info.bottom() - box_info.top() landmarks = landmark_predictor(frame, box_info) # 获得帽子图片的高height_hat,宽width_hat,便于后面控制帽子显示的大小 height_hat, width_hat = img_hat.shape[0], img_hat.shape[1] # 将帽子的高度变成,适合检测到的脸型的大小 imgComposeSizeH = int(height_hat / width_hat * width_face) # 因为帽子在脸部上方,当脸部靠近视频顶部,为了保证帽子能显示出来,帽子的高度默认为脸部到视频上方的距离 if imgComposeSizeH > (y0 - 20): imgComposeSizeH = (y0 - 20) # 将帽子的图片归一化到适合的宽和高大小,宽度为人脸的宽度,高度为上面调整后的帽子高度 imgComposeSize = cv2.resize(img_hat, (width_face, imgComposeSizeH), interpolation=cv2.INTER_NEAREST) top = (y0 - 20 - imgComposeSizeH ) # 当人脸太靠近图片上方,通过前一行的计算,有可能为负数,所以当出现这样的情况时,top设置为0 if top <= 0: top = 0 height_hat_new, width_hat_new = imgComposeSize.shape[0], imgComposeSize.shape[1] small_img_hat = frame[top:top + height_hat_new, x0:x0 + width_hat_new] # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("small_img_hat.jpg",small_img_hat) # 将帽子图像,从RGB彩色图像转换为灰度图像 small_img_hat_gray = cv2.cvtColor(imgComposeSize, cv2.COLOR_RGB2GRAY) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 ret, mask_hat = cv2.threshold(small_img_hat_gray, 10, 255, cv2.THRESH_BINARY) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("mask_hat.jpg", mask_hat) # 使用取反操作,将帽子的图像从黑色0变为白色255,将白色255变成黑色0 mask_hat_inv = cv2.bitwise_not(mask_hat) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("mask_hat_inv.jpg", mask_hat_inv) # 使用按位与操作,将抠出的帽子区域和取反后的帽子图像相加 img1_bg = cv2.bitwise_and(small_img_hat, small_img_hat, mask=mask_hat_inv) # 如需查看,上一行的效果,可将cv2.imwrite前面的#取消,运行后,保存到本目录查看 #cv2.imwrite("img1_bg.jpg", img1_bg) # 使用按位与操作,将像素值在[10,255]之间的帽子RGB区域抠取出来 img2_fg = cv2.bitwise_and(imgComposeSize, imgComposeSize, mask=mask_hat) # 将img1_bg和img2_fg相加,等于戴了帽子的区域图像 dst = cv2.add(img1_bg, img2_fg) frame[top:top + height_hat_new, x0:x0 + width_hat_new] = dst img = cv2.resize(frame, (800, 600)) # 显示图片 cv2.imshow("image", img) # 显示图片停顿的时间,如果是0,则一直显示。如果是100,则显示100ms if cv2.waitKey(2) & 0xFF == ord('q'): break # 按‘q’退出 ### 函数主入口 # if __name__ == '__main__': # 新建一个解析器 def maoc1(): parser = argparse.ArgumentParser() # 为解析器添加选项,比如image_path,添加图片地址,可以更换其他图片尝试。(在default后面,添加需要读取的图片路径) # 注意:不同的图片,宽高大小可能不同,大家可以根据自己的图片比例,调试前面的的cv2.resize中的数值,修改显示窗口的大小。 parser.add_argument('--video_path', default=0, help='path of cap video') # apath = os.path.abspath("mao1.png") # print(apath) # 为解析器添加选项,比如hat_path,添加帽子图片地址。(在default后面,添加需要读取的帽子图片路径) parser.add_argument('--hat_path', default="./image/m8.png", help='path of hat image') parser.add_argument('--landmarks_model_path', default="shape_predictor_68_face_landmarks.dat", help='path of model') # 解析选项的参数 opt = parser.parse_args() # 调用hat_face函数,对人脸进行检测,添加兔子帽子特效 hat_face(opt)
本作品是使用python语言进行开发设计,主要使用到pyqt5、opencv、dlib、math、requests、bs4等第三方库来实现。作品在读取图片和视频数据的功能上是使用opencv库来实现,除了对图像数据的读取外,还有一关键功能,就是为识别的人像进行68点关键点描点;dlib库是我们作品实现的关键技术,它是基于opencv对人像的描点进行检测,使人脸关键点定位更加精准,为我们后续的特效添加起到了重要的作用;并且通过dlib来进行调参算法对paddlehub框架进行优化;pyqt5模块支撑着我们作品的“排面”,界面设计简约,极易理解,非常容易上手。顺应时下流行的短视频媒体平台的潮流和广大用户的需要,以飞桨平台的模型调用便捷性,结合python开发技术,将图像视频处理工具进行打包,将一个具备免费、免安装、免网络的全民使用工具呈现给大家。
图像与视频的读取是我们工具必备的功能,图像和视频的读取不仅可以选择本地已有素材,在借助python的opencv模块功能下实现了可以实时进行拍摄、录制素材。在获取实时素材这一部分,我们加入了异常判断指令,使得获取的图像可以清晰、无延迟地显示到客户端,从而较好地实现了拍摄的实时效果,为后续对图片和视频进行处理奠定了基础。
这里提供简单的内容展示:
def Jietu(self): try: import time import win32com.client speak = win32com.client.Dispatch("SAPI.SpVoice") # speak.Speak("正在获取图片") self.da = [] times = str(round(time.time())) cap = cv2.VideoCapture(0) ret, frame = cap.read() # cao.read()返回两个值,第一个存储一个bool值,表示拍摄成功与否。第二个是当前截取的图片帧。 cv2.imwrite(f"./capture1_{times}.jpg", frame) # 写入图片 cap.release() # 释放 self.da.append(f"./capture1_{times}.jpg") time.sleep(0.2) self.labbeltu.setPixmap(QPixmap(self.da[0])) self.path_files1 = [1] self.path_files1[0] = self.da[0] speak.Speak("正在识别图片") except: pass
在图像处理中,关键点本质上是一种特征。它是对一个固定区域或者空间物理关系的抽象描述,描述的是一定邻域范围内的组合或上下文关系。它不仅仅是一个点信息,或代表一个位置,更代表着上下文与周围邻域的组合关系。关键点检测的目标就是通过计算机从图像中找出这些点的坐标,作为计算机视觉领域的一个基础任务,关键点的检测对于高级别任务,例如识别和分类具有至关重要的意义。
关键点检测方法总体上可以分成两个类型,一个种是用坐标回归的方式来解决,另一种是将关键点建模成热力图,通过像素分类任务,回归热力图分布得到关键点位置。这两个方法,都是一种手段或者是途径,解决的问题就是要找出这个点在图像当中的位置与关系。其中人脸关键点检测是关键点检测方法的一个成功实践。我们作品也将人脸关键点定位的功能完美应用其中。
这里提供 瘦脸优化 和 美白优化 的代码实例:
def thin_face(image, face_landmark):
"""
实现自动人像瘦脸
image: 人像图片
face_landmark: 人脸关键点
"""
end_point = face_landmark[30]
# 瘦左脸,3号点到5号点的距离作为瘦脸距离
dist_left = np.linalg.norm(face_landmark[3] - face_landmark[5])
image = local_traslation_warp(image, face_landmark[3], end_point, dist_left)
# 瘦右脸,13号点到15号点的距离作为瘦脸距离
dist_right = np.linalg.norm(face_landmark[13] - face_landmark[15])
image = local_traslation_warp(image, face_landmark[13], end_point, dist_right)
return image
def whitening(img, face_landmark): """ 美白 """ # 简单估计额头所在区域 # 根据0号、16号点画出额头(以0号、16号点所在线段为直径的半圆) radius=(np.linalg.norm(face_landmark[0] - face_landmark[16]) / 2).astype('int32') center_abs=tuple(((face_landmark[0] + face_landmark[16]) / 2).astype('int32')) angle=np.degrees(np.arctan((lambda l:l[1]/l[0])(face_landmark[16]-face_landmark[0]))).astype('int32') face = np.zeros_like(img) cv2.ellipse(face,center_abs,(radius,radius),angle,180,360,(255,255,255),2) # cv2.ellipse(face, center_abs, (radius, radius), angle, 180, 360, (0,0,0), 2) points=face_landmark[0:17] hull = cv2.convexHull(points) cv2.polylines(face, [hull], True, (255,255,255), 2) # cv2.polylines(face, [hull], True, (0,0,0), 2)
本功能是使用Pyqt5模块来进行工具GUI界面设计与制作。Pyqt5是基于图形程序框架Qt5的Python语言实现,由一组Python模块构成,是目前最主流的Python GUI框架。功能资源强大的同时又方便快捷。通过使用pyqt5模块可以很容易的对工具界面进行精美的设计和制作。并且在python打包的qt工具中,pyqt5库支持跨平台使用。
我们的工具主要对图片、视频进行处理,包括人像美颜、视频制作、等功能,具有方便、免安装、免费的优势。分为两大功能,分别是图片处理工具和视频处理工具,并且支持现场拍摄和现场录制视频来进行处理。
图片处理工具是本作品中的一种功能工具,它对于图片的风格化处理、图像质量的提升等功能有着很全面的实现,下面是图片处理工具的功能介绍图:
下面是我们的图片处理工具的界面图展示图:
可以通过选取本地图片或者现场拍摄的图片来选择瘦脸处理、眼睛处理、美白以及黑白图片上色等功能。
实时拍摄图片来进行处理,更是我们图像视频工具的一大特点:
操作流程:
Step1 选择需要处理的照片
可以选择本地已有的照片或者现场拍摄的照片
Step2 选择需要处理的功能
使用图片风格美化和图片质量提升等功能
Step3 进行美化处理
使用人像处理、人像美颜、图片上色,抠图等来对图片进行美化
Step4 检查图片
检查处理后的图片是否符合自己的要求
Step5 保存图片
将处理后的图片用原图进行保存
视频处理工具在本作品中,主要体现的是特效的添加。对于人脸的定位来进行精准的特效添加。
下面是我们作品的视频处理工具的界面展示图:
可以选择不同的特效来进行实时的录像。
效果展示图:
效果展示图:
操作流程:
Step 1 选择需要做处理的视频
可以直接添加本地视频或者现场实时录制视频
Step 2 选择需要的功能
工具中带有视频风格化处理、AI换脸、视频剪辑等功能
Step 3 进行调试
可以随意播放处理后视频,观看是否满足要求并进行调整
Step 4 保存视频
将处理后的视频保存到与原视频相同的路径下,并且不覆盖原视频
由于本作品是一款面向大众的功能性工具,而流程图是流经一个系统的信息流、观点流或部件流的图形代表,可以让用户更加直观的了解和使用我们的工具。下面是本工具的操作流程图:
用户可以根据我们的流程图通过简单的操作来实现图像视频处理。
经过几个月的设计和编码,作品《咔秀》基本开发完毕。基本实现了预定完成的功能。本文阐述了该工具的基础理论、实现过程和关键技术。由于篇幅的原因,不可能把整个系统中的每一项技术,每一个细节具体地讲出来,因此,我们只是有选择地对系统中的一些内容进行了介绍。不足之处,还望各位指教。
通过使用python语言中dilib人像关键点定位、opencv库等各种技巧,通过opencv库对图片和视频进行处理,使用photoshop工具设计图片。并且结合dlib库,利用设备摄像头进行人脸捕捉。从而定位人脸关键点,对人脸所在位置添加特效。
在作品设计期间,学习了python语言编程,用到的主要技术有pyqt5(界面设计)、opencv(读取摄像头)、dlib(人脸关键点定位)、、match(模块算法)、requests(数据获取)、bs4等主要技术,并查看学习了许多资料。在系统的研发过程中,我们也遇到许多困难,因为以前没有项目经验,起步很难,不过通过各种知识的补充学习,并且查找各种资料,团队慢慢进入状态,并且从中找到很多乐趣。
本系统经过测试,效果良好,但是由于时间有限,技术上存在许多需要改进之处。在功能上还有许多待完善的地方,比如可以增加特效种类,对特效进行动态处理在视频中增加互动,这些设想我们都在进一步的研究与实现。希望通过我们今后的不断努力,我们的作品不断扩大应用范围,真正服务于图片、视频特效这个领域。
此文仅为搬运,原作链接:https://aistudio.baidu.com/aistudio/projectdetail/4264449?channelType=0&channel=0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。