目录
一、dir及inspect函数的使用
(一)dir
(二)inspect
1、检查类型和成员
2、检索源代码
二、人脸比对
(一)人脸比对原理
(二)代码实现
三、 程序换脸
(一)前期准备
(二)代码实现
四、视频捕获人脸并实时标记人脸信息
一、dir及inspect函数的使用
(一)dir
Python内置函数 dir() 可以查看模块内定义的所有名称、属性,并以字符串列表的形式返回结果。
具体有如下两种形式:
- 当 dir() 不带参数时,返回当前范围内的变量、方法和定义的类型列表;
- 当 dir() 带参数时,返回参数的属性、方法列表。
语法为:
dir([object])
#object泛指具体的对象、变量、类型
例如:
不带参数时,获取当前模块的所有属性列表
带参数时,获取参数的属性、方法列表(以cv2为例)
(二)inspect
inspect 能够帮助用户获取对象的信息,例如模块、类、方法、函数、回溯、帧对象以及代码对象。 该模块提供了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函数的文档如下:
二、人脸比对
(一)人脸比对原理
首先程序判断导入的图片中有无人脸,分析脸的数据,并将各个关键点的数据进行记录,通过分析给定误差范围下的不同图片数据相似度,判断是否为同一个人。
(二)代码实现
本代码可实现对多张图片进行人脸比对,并输出待检测图片与已有图片的数据差异,具体如下:
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)
#输出样本图片及待识别图片的特征数据
实例如下:
图片:
程序运行结果:
三、 程序换脸
(一)前期准备
本程序运行需要调用Face++的API接口,主要作用为帮助程序查找人脸相关的数据,程序只需将图像上传到网站,即可调用后台服务器运算,对图像进行处理,并将处理后的结果返回,进而实现换脸。
需自行注册账号并生成自己的API接口。
(二)代码实现
以下代码能够实现基于图片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)
#将变量代入函数,数字为相似度
实例如下:
四、视频捕获人脸并实时标记人脸信息
以下代码能够实现实时检测视频中的人脸,并将其与已有的图片数据库进行比对,实时在视频中显示画面中所有的人脸名称。
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”
运行程序,识别下方图片
结果如下: