人脸识别程序

本文介绍了如何使用OpenCV和Dlib进行人脸识别,包括定位、对齐、识别等步骤,并解决了Dlib安装的问题。还涉及到人脸换脸的实现,以及通过Face++的API接口获取和处理人脸信息。最后提到了视频捕获人脸信息的挑战。

一、定位

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库  


2、使用pip install boost安装boost库

注:如果前两者有安装失败的也不用怕,可以在第三步完成后再安装1和2


3、下载VS2019(社区版免费)

下载链接: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()

 不放自己的脸了,视频抓拍真是要了命

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值