给图片中的人脸添加特效(帽子)

您所在的位置:网站首页 怎么给头像加口罩贴纸 给图片中的人脸添加特效(帽子)

给图片中的人脸添加特效(帽子)

2024-06-25 18:49| 来源: 网络整理| 查看: 265

给图片中的人脸添加特效(帽子) 人脸特效流程和原理拆解 1数据准备

首先要准备帽子和人脸照片,加载到项目的目录中

2人脸检测

首先调用OpenCV中的库函数对照片进行人脸检测,得到人脸矩形的各参数值,从而可以得到帽子要加在什么位置上去,由于人脸照片和帽子照片的大小位置的不同,所以当我们要将两个照片进行拼接的时候就得取人脸的上部分即额头的那一部分(如下图) 在这里插入图片描述 之后按照这个尺寸重新规划帽子的尺寸。

3灰度化帽子

因为我们要想得到两张照片拼接的样子,这就必须得用到OpenCV的另一个对图像处理的函数按像素相或的操作,所以我们需要准备出两张照片:1彩色帽子,黑色背景,2黑色帽子人额头和彩色背景 所以我们可以通过灰度二值化来减小问题的规模,因为RGB在这里是没有用的,保留反而会增加问题的复杂度,所以我们将帽子图片变成灰白的。

4阈值化帽子

灰度化操作之后就要将帽子变成黑白两色类似于0和1(255),全0为黑。我们不妨规定当灰度值大于10认定为是白色。

5取反帽子

顾名思义,白色帽子黑色背景的照片变成黑色帽子白色背景,为什么要这样做呢,别急看下一步。

6将黑帽子和白背景与人脸像素相与

利用OpenCV的按像素与操作将上一步得到的图片和之前的展示的人额头图片相与即可得到下幅图 在这里插入图片描述

7将白帽子黑背景与彩色帽子相与

将之前步骤获得的白色帽子黑背景的图片与相同比例的彩色帽子照片相与即可得到下面的图 在这里插入图片描述 有些伙伴可能会说这张图和一开始准备的帽子图有什么区别吗,唯一的区别就是这张图的尺寸是和人的额头那一种截取的照片是完美匹配的。

8将上两步的结果相或

这一步也能解决上一步中小伙伴存在的困惑,只有两张图尺寸完全一样才可以相或,最终的图片效果为下图所示 在这里插入图片描述 之后将这一部分图像直接在相应的位置赋值给原来的人脸图片即可得到最终的样式图。

视频特效制作

这里跟上面的主要区别就是从对图片的处理转移到视频的处理,方式很简单,就是把视频里的某一些等间隔的帧进行取出进行类似于图片处理的操作即可,这里直接上代码,注释也标得很清楚。

# -*- coding:utf-8 -*- """ 日期:2021年10月24日 """ import cv2 # 图像处理的opencv库 import math # 数学运算库 import dlib # 加载dlib算法模块 import argparse # 加载解析模块 def hat_face(opt): # 加载dlib自带的人脸检测模型 detector = dlib.get_frontal_face_detector() # 读取帽子样式的图片 img_hat = cv2.imread(opt.hat_path) # 使用opencv中的VideoCapture函数,读取视频 cap = cv2.VideoCapture(opt.video_path) # 初始化定义frame_id,便于后面跳帧 frame_id = 0 # 判断cap是否读取成功 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 # 如果frame_id除以10,不等于0,则不断循环,只有等于0时,才进行到下面的显示步骤,这样可以达到跳帧的效果 # 因为在算法处理中,比如一秒有25帧图像,为了提升项目速度,没有必要对每一帧都进行算法处理 # 注意:这里的10可以自行设置,如觉得跳帧太慢,可以设置大一些,比如15 if not int(frame_id) % 10 == 0: continue # 对读取的原始图像,进行人脸检测 faceRects = detector(frame) # 如果len(faces)>0,则说明图片上存在人脸 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() # 获得帽子图片的高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) # 为了实现在人脸上方的额头,添加兔子帽子特效,只需要将兔子帽子贴到额头处即可 # 注意:y0是人脸检测框左上方顶点的y坐标,y0-20,则差不多定位到额头处,再减去imgComposeSizeH,调整后兔子帽子的高度 # 即从这个位置开始贴合兔子帽子,可以实现人脸帽子特效 top = (y0 - 20 - imgComposeSizeH) # 当人脸太靠近图片上方,通过前一行的计算,有可能为负数,所以当出现这样的情况时,top设置为0 if top


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3