人脸识别有趣应用1——给自己带上胡子墨镜和帽子

前言

最近发现了一个好用的人脸识别python库,能够较为快速准确的识别人脸,并且能够识别出人脸的9个特征部位的特征点,包括:眉毛、眼睛、鼻子、嘴唇等,可以利用这个库结合笔者的实用工具集,加上一些逻辑运算,可以玩出各种花样。本次,我们来给人脸加上胡子、墨镜和帽子,效果如下:

在这里插入图片描述

基本原理

利用人脸识别库(face_recognition)逐帧识别摄像头的图像,获得人脸的左右眼眼睛,上嘴唇的特征点坐标系列,计算得到左右眼的中心,用opencv画出两个圆形,并用直线连接起来就成了一幅墨镜;再更具眼睛中心坐标在头上画椭圆就加了个帽子;胡子的画法:
利用ps画出想要的胡子形状,并保存为png透明背景格式,然后通过带alpha通道的操作,将胡子加载调整大小后,与当前的帧相叠加,就完成了初步效果。

Python源码

# -*- coding: utf-8 -*-
"""
Created on Thu Mar 31 18:12:53 2022
@author: JAMES FEI 
Copyright (C) 2022 FEI PANFENG, All rights reserved.
THIS SOFTEWARE, INCLUDING DOCUMENTATION,IS PROTECTED BY COPYRIGHT CONTROLLED 
BY FEI PANFENG ALL RIGHTS ARE RESERVED.

"""

# -*- coding: utf-8 -*-
"""
Created on Thu Mar 31 15:58:32 2022

@author: Administrator
"""

import face_recognition
import cv2
import numpy as np

video_capture = cv2.VideoCapture(0)

process_this_frame = True
 #载入胡子,带透明通道
huzi = cv2.imread('huzi.png', cv2.IMREAD_UNCHANGED)
ratio=1/4
huzi = cv2.resize(huzi, (int(huzi.shape[1]*ratio),int(huzi.shape[0]*ratio)), interpolation=cv2.INTER_LINEAR)

def putonhuzi(huzi,backimg,leftup):  
    
    #print(leftup)
    x1 = leftup[0]
    if x1<0:
        x1=0
    y1 = leftup[1]
    if y1<0:
        y1=0
    x2 = x1 + huzi.shape[1]
    y2 = y1 + huzi.shape[0] 
    usy=huzi.shape[0] 
    usx=huzi.shape[1]
    
    if x2>backimg.shape[1]:
        x2=backimg.shape[1]
        usx=backimg.shape[1]-x1
        
    if y2>backimg.shape[0]:
        y2=backimg.shape[1]
        usy=backimg.shape[0]-y1
    
    
    if backimg.shape[2] == 3:       
        b, g, r = cv2.split(backimg) 
        alpha = np.ones(b.shape, dtype=b.dtype) * 255 # 创建Alpha通道 
        backimg = cv2.merge((b, g, r, alpha))
 
    alpha_huzip = huzi[:usy,:usx,3] / 255.0
    alpha_huzij = 1 - alpha_huzip

    for c in range(0,3):
        backimg[y1:y2, x1:x2, c] = ((alpha_huzij*backimg[y1:y2,x1:x2,c]) + (alpha_huzip*huzi[:usy,:usx,c]))
    
    
    return backimg[:,:,:3]


while True:
    ret, frame = video_capture.read()

    small_frame = cv2.resize(frame, (0, 0), fx=1/4, fy=1/4)

    rgb_frame = small_frame[:, :, ::-1]

    if process_this_frame: 
        face_landmarks_list = face_recognition.face_landmarks(rgb_frame)
        for face_landmarks in face_landmarks_list:
        #打印此图像中每个面部特征的位置
            facial_features = [
                    
                    'chin',
                    'left_eyebrow',
                    'right_eyebrow',
                    'nose_bridge',
                    'nose_tip',
                    'left_eye',
                    'right_eye',
                    'top_lip',
                    'bottom_lip'
            ]


    lef_center_x=0
    lef_center_y=0
    
    for point in face_landmarks["left_eye"]:
            lef_center_x+=point[0]*4
            lef_center_y+=point[1]*4
    lef_center_x=int(lef_center_x/len(face_landmarks["left_eye"]))
    lef_center_y=int(lef_center_y/len(face_landmarks["left_eye"]))
    cv2.circle(frame, (lef_center_x,lef_center_y), 30, (0,0,0), -1)  
    rig_center_x=0
    rig_center_y=0
    
    for point in face_landmarks["right_eye"]:
            rig_center_x+=point[0]*4
            rig_center_y+=point[1]*4
    rig_center_x=int(rig_center_x/len(face_landmarks["left_eye"]))
    rig_center_y=int(rig_center_y/len(face_landmarks["left_eye"]))
    cv2.circle(frame, (rig_center_x,rig_center_y), 30, (0,0,0), -1)     
    cv2.line(frame, (rig_center_x,rig_center_y),(lef_center_x,lef_center_y), (0,0,0), 4)  
    cv2.ellipse(frame,(int((rig_center_x+lef_center_x)/2),int((rig_center_y+lef_center_y)/2-80)),(200,50),0,0,360, (0,0,0),-1)
    
    cv2.ellipse(frame,(int((rig_center_x+lef_center_x)/2),int((rig_center_y+lef_center_y)/2-100)),(90,60),0,0,360, (0,0,0),-1)
    
    top_lip_x=0
    top_lip_y=0
    
    for point in face_landmarks["top_lip"]:
        top_lip_x+=point[0]*4
        top_lip_y+=point[1]*4
    
    top_lip_x= int(top_lip_x/len(face_landmarks["top_lip"]))   
    top_lip_y= int(top_lip_y/len(face_landmarks["top_lip"]))  
    ouput=putonhuzi(huzi,frame,(top_lip_x-int(huzi.shape[1]/2),top_lip_y-20))

    cv2.imshow('huzi', ouput)

    # 按Q退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

video_capture.release()
cv2.destroyAllWindows()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340