一、定位
1.OpenCV定位
首先安装OpenCV,来定位多个人脸
在cmd中输入
pip install opencv-python
成功安装后就可以定位了
import cv2
import os
import matplotlib.pyplot as plt
os.chdir(‘需要识别的文件所在文件夹’)
#定义一个定位函数
def detect(filename):
face_cascade = cv2.CascadeClassifier(‘D:/FaceRuyi/data/haarcascade_frontalface_default.xml’)
img = cv2.imread(filename)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) #倒数第二个括号的参数是定义定位框的颜色,最后一个参数是框的边宽
plt.imshow(img)
plt.axis(‘off’) #去掉坐标轴
plt.show()
detect(‘用来定位的文件名’)
2.Dlib安装
Face-recognition 依赖于Dlib,Dlib依赖于OpenCV
定位比OpenCV更精确

问题① Dlib安装
直接使用pip install dlib安装总是报错,参考了dalao的安装步骤
作者原文链接如下:dlib安装
具体步骤:
1、使用pip install Cmake安装Cmake库
注:如果前两者有安装失败的也不用怕,可以在第三步完成后再安装1和2
下载链接:VS201
安装后选择vs安装管家
点击修改
安装python模块,如果之后选择vs开发的话还能选一些常用模块(c++, .net)
启动vs,就可以成功安装了
4.使用cmd打开系统命令提示符,输入pip install dlib
(1)使用默认的HOG算法定位
import face_recognition
import cv2
import matplotlib.pyplot as plt
image = face_recognition.load_image_file("要识别的文件名")
face_locations=face_recognition.face_locations(image)
face_num2=len(face_locations)
print(face_num2) # 识别到的人脸数量
org = cv2.imread("要识别的文件名")
for i in range(0,face_num2):
top = face_locations[i][0]
right = face_locations[i][1]
bottom = face_locations[i][2]
left = face_locations[i][3]
start = (left, top)
end = (right, bottom)
color = (0,255,255)
thickness = 2
img=cv2.rectangle(org, start, end, color, thickness)
plt.imshow(img)
plt.axis('off') #去掉坐标轴
plt.show()
(2)使用CNN(卷积神经网络)更精确
import face_recognition
import cv2
import matplotlib.pyplot as plt
image = face_recognition.load_image_file(要识别的文件名)
face_locations_useCNN = face_recognition.face_locations(image,model='cnn')
# model – Which face detection model to use. “hog” is less accurate but faster on CPUs.
# “cnn” is a more accurate deep-learning model which is GPU/CUDA accelerated (if available). The default is “hog”.
face_num1=len(face_locations_useCNN)
print(face_num1) # 识别到的人脸数量
org = cv2.imread(要识别的文件名)
for i in range(0,face_num1):
top = face_locations_useCNN[i][0]
right = face_locations_useCNN[i][1]
bottom = face_locations_useCNN[i][2]
left = face_locations_useCNN[i][3]
start = (left, top)
end = (right, bottom)
color = (0,255,255)
thickness = 2
img=cv2.rectangle(org, start, end, color, thickness) # opencv 里面画矩形的函数
plt.imshow(img)
plt.axis('off') #去掉坐标轴
plt.show()

二、人脸对齐
训练好的模型库文件(替换你的模型文件位置)
import cv2
import dlib
import matplotlib.pyplot as plt
path = "文件名"
img = cv2.imread(path)
#进行灰度处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#人脸分类器
detector = dlib.get_frontal_face_detector()
# 获取人脸检测器
predictor = dlib.shape_predictor(r"C:\Users\81244\AppData\Roaming\Python\Python37\site-packages\face_recognition_models\models\shape_predictor_68_face_landmarks.dat")
#predictor = r"C:\Users\81244\AppData\Roaming\Python\Python37\site-packages\face_recognition_models\models\shape_predictor_5_face_landmarks.dat")
dets = detector(gray, 1)
for face in dets:
#寻找人脸的68个标定点
shape = predictor(img, face)
#遍历所有点,打印出其坐标,并圈出来
for pt in shape.parts():
pt_pos = (pt.x, pt.y)
img=cv2.circle(img, pt_pos, 2, (0, 255, 0), 1) #第一个数字是圈的直径,括号里是圈的颜色,最后是圈的边宽
plt.imshow(img)
plt.axis('off') #去掉坐标轴
plt.show()

三、人脸识别
#依旧先引用库+修改目录
import os
import cv2
import face_recognition
import matplotlib.pyplot as plt
os.chdir(r'C:\Users\81244\Desktop\Python practice')
print(os.getcwd())
#读取需要对比的两张图片
known_image=cv2.imread("zyl.jpg")
known_image=face_recognition.load_image_file("zyl.jpg")
unknown_image=cv2.imread("lyx.jpg")
unknown_image=face_recognition.load_image_file("lyx.jpg")
问题② 图片文件的编码
known_encoding = face_recognition.face_encodings(known_image)[0]
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
这里的face_encodings函数是用来获取每个图像文件中每个面部的面部编码,因为准备的图片素材里面每张只有一个脸,所以直接就取第零个元素了。
但是这里出现的一个问题是,用我自己的自拍时无法进行编码!查找其他文章后推测应该是由于图片的大小大于2M。
P.S. 后面使用Face++进行换脸时,也要求了图片大小不能超过2M。
#得到比对结果并设置误差范围(我觉得0.5差不多,0.4也行,0.6的话比对老是出错)
results = face_recognition.compare_faces([known_encoding],unknown_encoding,tolerance=0.5)
if results[0]==True:
print("匹配成功,该未知图片与已有图片人脸可匹配!")
else:
print("匹配失败!")
dis1=face_recognition.face_distance([known_encoding],unknown_encoding)
print("人脸对比数据差异:")
print(dis1)
#图片放出来看一下
print(type(known_image))
plt.imshow(known_image)
plt.axis('off')
plt.show()
plt.imshow(unknown_image)
plt.axis('off')
plt.show()
结果如下:

四、换脸
需要用到Face++的API接口,自己去官网注册一下就可以获得自己的API啦

需要用到的各种库
#JSON是存储和交换文本信息的语法,类似 XML
import requests
import simplejson
import json
import base64
from matplotlib import pyplot as plt
#Face++网址:[url]https://console.faceplusplus.com.cn/dashboard[/url]
第一步,定义一个获取人脸特征点的函数
def find_face(imgpath):
print("正在查找……")
#用来进行人脸识别的网站地址
http_url = 'https://api-cn.faceplusplus.com/facepp/v3/detect'
#这里就是自己的API参数
data = {"api_key": '64DKE-FiMFyeStDnJPYh9kdt1uLKbzyQ',
"api_secret": 'zdfMX8FbDQWo7W4OPwAEd0Q8hLvEO5Jd',
"image_url": imgpath, "return_landmark": 1}
#使用二进制方式读取图片
files = {"image_file": open(imgpath, "rb")}
#向网站提交请求
response = requests.post(http_url, data=data, files=files)
#response.content为bytes类型,decode() 将它转换为utf8
#后面就是利用json进行数据的编码解码
req_con = response.content.decode('utf-8')
req_dict = json.JSONDecoder().decode(req_con)
this_json = simplejson.dumps(req_dict)
this_json2 = simplejson.loads(this_json)
faces = this_json2['faces']
list0 = faces[0]
rectangle = list0['face_rectangle']
#print(rectangle)
#返回得到的人脸特征数据
return rectangle
第二步,定义换脸函数
#number表示换脸的相似度
def merge_face(image_url1, image_url2, image_url, number):
#先处理一下两张图片,得到各种坐标
ff1 = find_face(image_url1)
ff2 = find_face(image_url2)
rectangle1 = str(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'])
#print(rectangle2)
#打开图片并将字符串转成成base64编码
url_add = "https://api-cn.faceplusplus.com/imagepp/v1/mergeface"
f1 = open(image_url1, 'rb')
f1_64 = base64.b64encode(f1.read())
f1.close()
f2 = open(image_url2, 'rb')
f2_64 = base64.b64encode(f2.read())
f2.close()
#依旧是向网站发送请求
data = {"api_key": '64DKE-FiMFyeStDnJPYh9kdt1uLKbzyQ',
"api_secret": 'zdfMX8FbDQWo7W4OPwAEd0Q8hLvEO5Jd',
"template_base64": f1_64, "template_rectangle": rectangle1,
"merge_base64": f2_64, "merge_rectangle": rectangle2, "merge_rate": number}
response = requests.post(url_add, data=data)
req_con1 = response.content.decode('utf-8')
req_dict = json.JSONDecoder().decode(req_con1)
#得到返回的参数,并写入新的图片
result = req_dict['result']
imgdata = base64.b64decode(result)
file = open(image_url, 'wb')
file.write(imgdata)
file.close()
主函数读入图片,然后调用写好的函数,结束后显示新图片
image1 = r"C:\Users\81244\Desktop\Python practice\zyl.jpg"
image2=r"C:\Users\81244\Desktop\Python practice\lyx.jpg"
#这里写的是新生成的图片
image=r"C:\Users\81244\Desktop\Python practice\change2.jpg"
merge_face(image2, image1, image, 90)
#展示
img1=plt.imread(r'C:\Users\81244\Desktop\Python practice\zyl.jpg')
plt.axis('off')
plt.imshow(img1)
plt.show()
img2=plt.imread(r'C:\Users\81244\Desktop\Python practice\lyx.jpg')
plt.axis('off')
plt.imshow(img2)
plt.show()
img0=plt.imread(r'C:\Users\81244\Desktop\Python practice\change2.jpg')
plt.axis('off')
plt.imshow(img0)
plt.show()
看一下结果,还可以吼!


五、视频捕获人脸信息
import cv2
import dlib
#开摄像头(ESC退出
cap = cv2.VideoCapture(0)
predictor_path = r"C:\Python36\Lib\site-packages\face_recognition_models\models\shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(predictor_path)
detector = dlib.get_frontal_face_detector()
while True:
_, frame = cap.read()
# 在视频里抓取一帧然后找里边的脸
dets = detector(frame, 1)
#if len(dets) != 0:
for i in range(len(dets)):
# Get the landmarks/parts for the face in box d.
shape = predictor(frame, dets[0])
for p in shape.parts():
cv2.circle(frame, (p.x, p.y), 3, (0, 0, 0), -1)
cv2.imshow('video', frame)
#设置退出
if cv2.waitKey(1) & 0xFF == 27:
break
cap.release()
cv2.destroyAllWindows()
不放自己的脸了,视频抓拍真是要了命
本文介绍了如何使用OpenCV和Dlib进行人脸识别,包括定位、对齐、识别等步骤,并解决了Dlib安装的问题。还涉及到人脸换脸的实现,以及通过Face++的API接口获取和处理人脸信息。最后提到了视频捕获人脸信息的挑战。


7888

被折叠的 条评论
为什么被折叠?



