目录

一、dir及inspect函数的使用 

(一)dir

(二)inspect

1、检查类型和成员

2、检索源代码

二、人脸比对

(一)人脸比对原理

(二)代码实现

三、 程序换脸

(一)前期准备

(二)代码实现

 四、视频捕获人脸并实时标记人脸信息


一、dir及inspect函数的使用 

(一)dir

Python内置函数 dir() 可以查看模块内定义的所有名称、属性,并以字符串列表的形式返回结果。

具体有如下两种形式:

  1. 当 dir() 不带参数时,返回当前范围内的变量、方法和定义的类型列表;
  2. 当 dir() 带参数时,返回参数的属性、方法列表。

语法为:

dir([object])
#object泛指具体的对象、变量、类型

例如:

不带参数时,获取当前模块的所有属性列表

python 视频换脸技术原理 python怎么给视频换脸_人脸识别

 带参数时,获取参数的属性、方法列表(以cv2为例)

python 视频换脸技术原理 python怎么给视频换脸_json_02

(二)inspect

inspect 能够帮助用户获取对象的信息,例如模块、类、方法、函数、回溯、帧对象以及代码对象。 该模块提供了4种主要的功能:

  1. 类型检查
  2. 获取源代码
  3. 获取类或者函数的参数信息
  4. 检查解释器的调用堆栈

 以下为inspect模块中常用的查看方法:

1、检查类型和成员

语法为:

import inspect
#导入inspect库

inspect.getmembers(object[, predicate])
#predicate是一个可选的函数参数,被此函数判断为True的成员才被返回

该函数获取对象的成员,例如类或模块。函数名以"is"开始的函数主要作为 getmembers() 的第2个参数使用。主要有如下几类:

inspect.ismodule(object)
#检查是否为模块

inspect.isclass(object)
#检查是否为类

inspect.ismethod(object)
#检查是否为方法(bound method written in python)

inspect.isfunction(object)
#检查是否为函数(python function, including lambda expression)

inspect.isgeneratorfunction(object)
#检查是否为python生成器函数

inspect.isgenerator(object)
#检查是否为生成器

inspect.istraceback(object)
#检查是否为traceback

inspect.isframe(object)
#检查是否为frame

inspect.iscode(object)
#检查是否为code

inspect.isbuiltin(object)
#检查是否为built-in函数或built-in方法

inspect.isroutine(object)
#检查是否为用户自定义或者built-in函数或方法

inspect.isabstract(object)
#检查是否为抽象基类

inspect.ismethoddescriptor(object)
#检查是否为方法标识符

inspect.isdatadescriptor(object)
#检查是否为数字标识符,数字标识符有__get__ 和__set__属性; 通常也有__name__和__doc__属性

inspect.isgetsetdescriptor(object)
#检查是否为getset descriptor

inspect.ismemberdescriptor(object)
#检查是否为member descriptor

2、检索源代码

语法为:

import inspect
#导入inspect库

inspect.getdoc(object)
#获取对象的文档字符串,如果没有则返回None

inspect.getcomments(object)
#以单个字符串的形式返回紧位于对象源代码(用于类、方法或者函数)之前的任何注释行,或者位于Python源文件的顶部(如果对象是个模块)。如果源代码不可用则返回None

inspect.getfile(object)
#返回定义对象的文件路径

inspect.getmodule(object)
#返回对象所属的模块名

inspect.getsourcefile(object)
#返回对象的python源文件名

inspect.getsourcelines(object)
#返回对象的python源文件代码的内容

inspect.getsource(object)
#以字符串形式返回对象的源代码

例如,读取cv2模块中circle函数的文档如下:

python 视频换脸技术原理 python怎么给视频换脸_python 视频换脸技术原理_03

二、人脸比对

(一)人脸比对原理

首先程序判断导入的图片中有无人脸,分析脸的数据,并将各个关键点的数据进行记录,通过分析给定误差范围下的不同图片数据相似度,判断是否为同一个人。

(二)代码实现

本代码可实现对多张图片进行人脸比对,并输出待检测图片与已有图片的数据差异,具体如下:

import cv2
import face_recognition
import matplotlib.pyplot as plt
#引入第三方库

known_image=cv2.imread("yang1.jpg")
known_image=face_recognition.load_image_file("yang1.jpg")
#读取样本图片

known_encoding=face_recognition.face_encodings(known_image)[0]
#分析样本图片

unknown_image1=cv2.imread("guo1.jpg")
unknown_image1=face_recognition.load_image_file("guo1.jpg")
#读取待识别图片1

unknown_encoding1=face_recognition.face_encodings(unknown_image1)[0]
#分析待识别图片1


results1=face_recognition.compare_faces([known_encoding],
                                       unknown_encoding1,
                                        tolerance=0.5)
#将图片进行比对,并制定误差范围

if results1[0] == True:
    print("图片1与已有图片人脸匹配成功!")
else:
    print("图片1与已有人脸图片匹配失败!")
#输出匹配结果1

dis1=face_recognition.face_distance([known_encoding],unknown_encoding1)
print("图片1与已有图片的详细对比数据差异:")
print(dis1)
#计算并输出图片对比详细数据差异

unknown_image2=cv2.imread("yang2.jpg")
unknown_image2=face_recognition.load_image_file("yang2.jpg")
#读取待识别图片2

unknown_encoding2=face_recognition.face_encodings(unknown_image2)[0]
#分析待识别图片2


results2=face_recognition.compare_faces([known_encoding],
                                       unknown_encoding2,
                                        tolerance=0.5)
#将图片进行比对,并制定误差范围

if results2[0] == True:
    print("图片2与已有图片人脸匹配成功!")
else:
    print("图片2与已有人脸图片匹配失败!")
#输出匹配结果2

dis2=face_recognition.face_distance([known_encoding],unknown_encoding2)
print("图片2与已有图片的详细对比数据差异:")
print(dis2)
#计算并输出图片对比详细数据差异
    
#print(known_encoding) 
#print(unknown_encoding)
#输出样本图片及待识别图片的特征数据

实例如下:

图片:

python 视频换脸技术原理 python怎么给视频换脸_数据_04

 程序运行结果:

python 视频换脸技术原理 python怎么给视频换脸_人脸识别_05

三、 程序换脸

(一)前期准备

本程序运行需要调用Face++的API接口,主要作用为帮助程序查找人脸相关的数据,程序只需将图像上传到网站,即可调用后台服务器运算,对图像进行处理,并将处理后的结果返回,进而实现换脸。

需自行注册账号并生成自己的API接口。

python 视频换脸技术原理 python怎么给视频换脸_人脸识别_06

(二)代码实现

以下代码能够实现基于图片1,将图片2中的人脸融合到图片1中,进而实现换脸。

import json
import requests
import simplejson
import base64
#引入第三方库

def find_face(imgpath):
    #找到人脸数据,获取人脸关键点
    http_url = 'https://api-cn.faceplusplus.com/facepp/v3/detect'
    data = {
            "api_key":'PzjDe5twKViFooMe02TSvs4rBzPWx85T',
            "api_secret":'mxUCyhNcbWYO3Mdi_6_d1EUJm8SP6J-Y',
            "image_url":imgpath,
            #图片路径
            "return_landmark":1
            #返回的人脸区域坐标
            }
    
    files = {'image_file':open(imgpath,'rb')}
    #rb表示二进制的读取
    response = requests.post(http_url,data=data,files=files)
    #使用post请求
    req_con = response.content.decode('utf-8')
    this_json = simplejson.loads(req_con)
    faces = this_json['faces']
    list0 = faces[0]
    rectangle = list0['face_rectangle']

    return rectangle
    #返回面部数据

def merge_face(image_url1,image_url2,image_url,number):
    #拼合人脸
    ff1 = find_face(image_url1)
    ff2 = find_face(image_url2)
    #获取两张图片的人脸数据

    f1 = open(image_url1,'rb')
    f1_64 = base64.b64encode(f1.read())
    f1.close()
    #定义base64编码后的模板图片

    f2 = open(image_url2,'rb')
    f2_64 = base64.b64encode(f2.read())
    f2.close()
    #定义base64编码后的待拼合图片

    rectangle1 = str(ff1['top']) + "," + str(ff1['left']) + "," + str(ff1['width'])+ "," + str(ff1['height'])
    rectangle2 = str(ff2['top']) + "," + str(ff2['left']) + "," + str(ff2['width'])+ "," + str(ff2['height'])
    #因后续所需参数需为字符串类型,而ff1和ff2都是字典,故此处进行格式转换

    url_add = 'https://api-cn.faceplusplus.com/imagepp/v1/mergeface'
    data = {
        "api_key":'PzjDe5twKViFooMe02TSvs4rBzPWx85T',"api_secret":'mxUCyhNcbWYO3Mdi_6_d1EUJm8SP6J-Y',
        "template_base64":f1_64,"template_rectangle":rectangle1,
        "merge_base64":f2_64,"merge_rectangle":rectangle2,"merge_rate":number
    }

    response1 = requests.post(url_add,data=data)
    print(response1)
    req_con1 = response1.content.decode('utf-8')

    req_dict = json.JSONDecoder().decode(req_con1)
    print(req_dict)
    result = req_dict['result']
    imgdata = base64.b64decode(result)

    file = open(image_url,'wb')
    file.write(imgdata)
    file.close()

image1 = r"1.jpg"
image2 = r"2.jpg"
image = r"face.jpg"
#导入具体变量
#image1为模板图片,image2为待拼合图片,image为拼合后的图片名称

merge_face(image1,image2,image,100)
#将变量代入函数,数字为相似度

实例如下:

python 视频换脸技术原理 python怎么给视频换脸_python 视频换脸技术原理_07

 四、视频捕获人脸并实时标记人脸信息

以下代码能够实现实时检测视频中的人脸,并将其与已有的图片数据库进行比对,实时在视频中显示画面中所有的人脸名称。

import cv2
import face_recognition
import os
#导入第三方库

cap = cv2.VideoCapture(0)
#打开摄像头

path ="pic"
#在同级目录下的pic文件中存放人物图像库

total_image=[]
total_image_name=[]
total_face_encoding=[]
#定义图像库数据

for filename in os.listdir(path):
    #filename表示文件名
  total_face_encoding.append(face_recognition.face_encodings(face_recognition.load_image_file(path+"/"+filename))[0])
  filename=filename[:(len(filename)-4)]
  #从源文件中截取图像名称
  #pic文件中的图像应命名为人物名
  total_image_name.append(filename)
  #添加图像名字至列表
  
while True:
  ret, frame = cap.read()
  #从视频中抓取一帧
  face_locations = face_recognition.face_locations(frame)
  face_encodings = face_recognition.face_encodings(frame, face_locations)
  #发现在视频帧所有的脸和face_enqcodings
  for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
      #循环遍历视频中的每个人脸
      for i,v in enumerate(total_face_encoding):
          match = face_recognition.compare_faces([v], face_encoding,tolerance=0.5)
          name = "Unknown"
          if match[0]:
              name = total_image_name[i]
              break
        #检验视频中的面部数据是否与已知人脸相匹配

      cv2.rectangle(frame, (left, top), (right, bottom), (100, 200, 255), 2)
      #绘制人脸识别框

      cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (100, 200, 255), cv2.FILLED)
      font = cv2.FONT_HERSHEY_DUPLEX
      cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
      #在人脸识别框下,绘制人脸标签
      

  cv2.imshow('Video', frame)
  #显示结果图像

  if cv2.waitKey(1) & 0xFF == 27:
        break
    #设置退出键
    
cap.release()
cv2.destroyAllWindows()
#释放摄像头

 实例如下:

在程序目录下,新建名为“pic”的文件夹,用于存放人脸图像库图片。其中,人脸图片命名格式为“英文字符+.jpg”

python 视频换脸技术原理 python怎么给视频换脸_数据_08

 运行程序,识别下方图片

python 视频换脸技术原理 python怎么给视频换脸_json_09

 结果如下:

python 视频换脸技术原理 python怎么给视频换脸_python_10