文章目录

  • 问题描述
  • 解决方案
  • 安装
  • 人脸检测
  • 1. HARR特征级联分类器
  • 2. LBP特征级联分类器
  • 3. DNN预训练模型
  • 4. MTCNN预训练模型
  • 5. HOG人脸检测器
  • 6. MMOD预训练模型
  • 7. RetinaFace预训练模型
  • 运算时间
  • 人脸识别
  • 1. LBPH人脸识别器
  • 2. OpenFace人脸识别器(尚未完成)
  • 3. DeepID人脸识别器(尚未完成)
  • 4. FaceNet人脸识别器(尚未完成)
  • 5. InsightFace(尚未完成)
  • 6. ArcFace(尚未完成)
  • 摄像头捕获
  • 戴圣诞帽
  • TODO
  • 人脸识别常用数据集
  • 备注
  • 参考文献



本文代码、图片及模型下载地址

问题描述

1.jpg

python人脸识别肤色人种 python 人脸_计算机视觉


2.jpg

python人脸识别肤色人种 python 人脸_计算机视觉_02


人脸检测:把人脸框出来。

人脸对齐:把人脸的关键点定位出来。

人脸识别:判断出谁是谁。


解决方案

  1. 人脸检测,收集人脸数据
  2. 提取人脸深度特征
  3. 训练人脸识别分类器
  4. 人脸检测,调用识别分类器进行人脸识别


安装

pip install opencv-python
pip install opencv-contrib-python


人脸检测

1. HARR特征级联分类器

使用 OpenCV 的级联分类器 CascadeClassifier 加载预训练模型 haarcascade_frontalface_default.xml,该模型使用 AdaBoost 算法,运行速度十分快,在2013年12月19日上传。

代码

import cv2

# 读取文件
image = '1.jpg'
model = 'haarcascade_frontalface_default.xml'
image = cv2.imread(image)  # 读取图片
model = cv2.CascadeClassifier(model)  # 加载模型

# 人脸检测
faces = model.detectMultiScale(image)
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)  # 画出人脸矩形框

# 显示和保存图片
cv2.imshow('result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('result.jpg', image)
print('已保存')

效果

python人脸识别肤色人种 python 人脸_人脸识别_03


python人脸识别肤色人种 python 人脸_python_04

缺点:

  1. 仅适用于正面人脸。
  2. 鲁棒性不足,经常翻车。例如衣服有个地方很像人脸也会检测出来。


2. LBP特征级联分类器

使用 OpenCV 的级联分类器 CascadeClassifier 加载预训练模型 lbpcascade_frontalface_improved.xml,该模型在2016年12月21日上传。

代码

import cv2

# 读取文件
image = '1.jpg'
model = 'lbpcascade_frontalface_improved.xml'
image = cv2.imread(image)  # 读取图片
model = cv2.CascadeClassifier(model)  # 加载模型

# 人脸检测
faces = model.detectMultiScale(image)
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)  # 画出人脸矩形框

# 显示和保存图片
cv2.imshow('result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('result.jpg', image)
print('已保存')

效果

python人脸识别肤色人种 python 人脸_python人脸识别肤色人种_05


python人脸识别肤色人种 python 人脸_opencv_06


3. DNN预训练模型

使用 OpenCV 的 DNN 人脸识别预训练模型,该模型基于残差网络 ResNet-10 的 SSD 网络模型,运行速度十分快,在2018年上传。

  • Caffe模型
  • TensorFlow模型

代码

import cv2
import numpy as np

# 读取文件
image = '1.jpg'
net = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'res10_300x300_ssd_iter_140000_fp16.caffemodel')  # Caffe模型
# net = cv2.dnn.readNetFromTensorflow('opencv_face_detector_uint8.pb', 'opencv_face_detector.pbtxt')  # TensorFlow模型
image = cv2.imread(image)  # 读取图片
height, width, channel = image.shape  # 高、宽、通道数

# 人脸检测
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0))  # 调整大小并降低光照的影响
net.setInput(blob)  # 设置输入
detections = net.forward()  # 检测结果
faces = detections[0, 0]  # 人脸结果
for face in faces:
    confidence = face[2]  # 置信度
    if confidence > 0.5:  # 置信度阈值设为0.5
        box = face[3:7] * np.array([width, height, width, height])  # 人脸矩形框坐标
        pt1 = int(box[0]), int(box[1])  # 左上角坐标
        pt2 = int(box[2]), int(box[3])  # 右下角坐标
        cv2.rectangle(image, pt1, pt2, (0, 255, 0), thickness=2)  # 画出人脸矩形框

        text = '{:.2f}%'.format(confidence * 100)  # 置信度文本
        startX, startY = pt1
        y = startY - 10 if startY - 10 > 10 else startY + 10
        org = (startX, y)  # 文本的左下角坐标
        cv2.putText(image, text, org, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), thickness=2)  # 画出置信度

# 显示和保存图片
cv2.imshow('result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('result.jpg', image)
print('已保存')

效果

python人脸识别肤色人种 python 人脸_python人脸识别肤色人种_07


python人脸识别肤色人种 python 人脸_python人脸识别肤色人种_08

小男孩人脸置信度仅为50.38%,有待提高


4. MTCNN预训练模型

MTCNN 即 Multi-task Cascaded Convolutional Networks ,多任务级联卷积神经网络,可完成人脸检测和人脸对齐。

代码

import cv2
import detect_face
import tensorflow as tf

# 读取文件
image = '1.jpg'
image = cv2.imread(image)  # 读取图片
pnet, rnet, onet = detect_face.create_mtcnn(tf.Session(), None)  # 加载模型

# 人脸检测
minsize = 20  # 人脸最小尺寸
threshold = [0.6, 0.7, 0.7]  # MTCNN三个阶段的阈值
factor = 0.709  # 人脸大小缩放金字塔的比例
margin = 44  # 边框周围的裁剪边距
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
faces, _ = detect_face.detect_face(image_rgb, minsize, pnet, rnet, onet, threshold, factor)
for face in faces:
    face = face.astype(int)
    (x, y, w, h) = face[:4]
    cv2.rectangle(image, (x, y), (w, h), (0, 255, 0), thickness=2)  # 画出人脸矩形框

# 显示和保存图片
cv2.imshow('result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('result.jpg', image)
print('已保存')

若报错 TypeError: reduce_max() got an unexpected keyword argument 'keepdims' ,原因是TensorFlow版本低于1.7.0,将 keepdims 替换成 keep_dims 即可

效果

python人脸识别肤色人种 python 人脸_python人脸识别肤色人种_09


python人脸识别肤色人种 python 人脸_人脸识别_10


5. HOG人脸检测器

使用 DlibHOG人脸检测器

安装步骤:

  1. CMake,将 bin 目录添加到环境变量 PATH 中。
  2. Dlib
  3. 若安装失败,可能还需要Visual Studio,本人使用2015

代码

import cv2
import dlib

# 读取文件
image = '1.jpg'
image = cv2.imread(image)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 人脸检测
model = dlib.get_frontal_face_detector()  # 加载模型
faces = model(image_rgb, 1)
for face in faces:
    (x, y, w, h) = face.left(), face.top(), face.right(), face.bottom()
    cv2.rectangle(image, (x, y), (w, h), (0, 255, 0), thickness=2)  # 画出人脸矩形框

# 显示和保存图片
cv2.imshow('result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('result.jpg', image)
print('已保存')

效果

python人脸识别肤色人种 python 人脸_计算机视觉_11


python人脸识别肤色人种 python 人脸_python_12


6. MMOD预训练模型

使用 DlibMMOD人脸检测器,基于 DNN 实现,下载预训练模型 mmod_human_face_detector.dat.bz2 并解压。

代码

import cv2
import dlib

# 读取文件
image = '1.jpg'
image = cv2.imread(image)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 人脸检测
model = dlib.cnn_face_detection_model_v1('mmod_human_face_detector.dat')  # 加载模型
faces = model(image_rgb, 1)
for face in faces:
    face = face.rect
    (x, y, w, h) = face.left(), face.top(), face.right(), face.bottom()
    cv2.rectangle(image, (x, y), (w, h), (0, 255, 0), thickness=2)  # 画出人脸矩形框

# 显示和保存图片
cv2.imshow('result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('result.jpg', image)
print('已保存')

效果

python人脸识别肤色人种 python 人脸_opencv_13


python人脸识别肤色人种 python 人脸_计算机视觉_14


7. RetinaFace预训练模型

使用 InsightFaceRetinaFace 预训练模型,该模型达到了 WiderFace 的 SOTA。

安装

pip install insightface

代码

import cv2
from insightface.model_zoo import face_detection

# 读取文件
image = cv2.imread('1.jpg')  # 读取图片
model = face_detection.retinaface_r50_v1()  # 加载模型
model.prepare(ctx_id=-1, nms=0.4)

# 人脸检测
faces, landmark = model.detect(image, threshold=0.5, scale=1.0)
for face in faces:
    (x, y, w, h, confidence) = face
    pt1 = int(x), int(y)
    pt2 = int(w), int(h)
    cv2.rectangle(image, pt1, pt2, (0, 255, 0), thickness=2)  # 画出人脸矩形框

    text = '{:.2f}%'.format(confidence * 100)  # 置信度文本
    startX, startY = pt1
    y = startY - 10 if startY - 10 > 10 else startY + 10
    org = (startX, y)  # 文本的左下角坐标
    cv2.putText(image, text, org, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), thickness=2)  # 画出置信度

# 显示和保存图片
cv2.imshow('result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('result.jpg', image)
print('已保存')

效果

python人脸识别肤色人种 python 人脸_python人脸识别肤色人种_15


python人脸识别肤色人种 python 人脸_opencv_16


运算时间

对比不同方法的运算时间

import cv2
import time
import numpy as np

# 读取图片
image = '2.jpg'
image = cv2.imread(image)

# 级联分类器
model = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')  # 加载模型
beg = time.time()
faces = model.detectMultiScale(image)
end = time.time()
print('级联分类器 {:.2f} s'.format(end - beg))

# DNN Caffe模型
net = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'res10_300x300_ssd_iter_140000_fp16.caffemodel')  # Caffe模型
beg = time.time()
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()
end = time.time()
print('DNN Caffe模型 {:.2f} s'.format(end - beg))

# DNN TensorFlow模型
net = cv2.dnn.readNetFromTensorflow('opencv_face_detector_uint8.pb', 'opencv_face_detector.pbtxt')  # TensorFlow模型
beg = time.time()
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()
end = time.time()
print('DNN TensorFlow模型 {:.2f} s'.format(end - beg))

结果

模型

大小

运算时间

级联分类器

0.89 MB

0.35 s

Caffe模型

5.12 MB

0.04 s

TensorFlow模型

2.63 MB

0.04 s


人脸识别

1. LBPH人脸识别器

使用 LBPHFaceRecognizer (Local Binary Patterns Histograms),局部二值模式直方图,可降低特征维度。而OpenCV另两个人脸识别算法 EigenFaceRecognizerFisherFaceRecognizer 考虑总体特征。

image

python人脸识别肤色人种 python 人脸_人脸识别_17


代码

import os
import cv2
import time
import sqlite3
import pathlib
import numpy as np
from tkinter import *
from PIL import Image, ImageTk, ImageFont, ImageDraw

name = ''  # 当前人脸的名字
lastid = 0  # 用户最新的id
id_name_map = {}  # 用户id对应名字
name_id_map = {}  # 用户名对应id


def cv2_putChinese(image, chinese, xy, font='msyh.ttc', size=25, fill=(255, 0, 0)):
    """cv2转PIL绘制中文后转回cv2"""
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image = Image.fromarray(image)
    font = ImageFont.truetype(font, size)
    draw = ImageDraw.Draw(image)
    draw.text(xy, chinese, font=font, fill=fill)
    image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
    return image


def show_on_tkinter(image, title):
    """用tkinter显示图片"""

    def save(event):
        global name
        global lastid
        name = entry.get()
        if name:
            if name not in name_id_map:
                c.execute('INSERT INTO users (`name`) VALUES (?)', (name,))  # 插入数据库
                conn.commit()  # 提交
                lastid += 1  # 更新用户最新的id
                id_name_map[lastid] = name
                name_id_map[name] = lastid  # 更新所有用户
                if name_id_map:
                    print('数据库中的用户有: {}'.format(' '.join(name_id_map)))  # 所有用户
            os.makedirs('dataset/{}'.format(name), exist_ok=True)  # 保存人脸图像目录
            filename = 'dataset/{}/{}.jpg'.format(name, int(time.time()))  # 保存人脸图像文件名
            image.save(filename)  # 用Image.save()避免cv2.imwrite()不能中文名的缺点
        window.destroy()

    window = Tk()
    window.title(title)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    height, width, channels = image.shape
    canvas = Canvas(window, width=width, height=height)
    canvas.pack()
    image = Image.fromarray(image)
    photo = ImageTk.PhotoImage(image)
    canvas.create_image(0, 0, image=photo, anchor=NW)
    label = Label(window, text='输入姓名,空则跳过')
    label.pack(anchor=CENTER)
    entry = Entry(window)
    entry.pack(anchor=CENTER)
    entry.focus_force()
    entry.bind('<Return>', func=save)
    window.mainloop()


# 人脸数据库
conn = sqlite3.connect('database.db')  # 人脸数据库
c = conn.cursor()
sql = '''
CREATE TABLE IF NOT EXISTS users (
   `id` INTEGER UNIQUE PRIMARY KEY AUTOINCREMENT,
   `name` TEXT UNIQUE
);
'''
c.execute(sql)  # 用户表
users = c.execute('SELECT * FROM users')
for (id, name) in users:
    lastid = id
    id_name_map[lastid] = name
    name_id_map[name] = id
if name_id_map:
    print('数据库中的用户有: {}'.format(' '.join(name_id_map)))  # 所有用户

# 记录人脸
os.makedirs('dataset', exist_ok=True)  # 保存人脸图像目录
model = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')  # 加载模型
images = pathlib.Path('image').rglob('*')
for image in images:
    print('正在处理: {}'.format(image))
    image = str(image)
    image = cv2.imread(image)
    original = image.copy()
    cv2.imshow('original', original)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 转灰度图
    faces = model.detectMultiScale(gray)
    for i, (x, y, w, h) in enumerate(faces):
        face = image[y:y + h, x:x + w]
        cv2.rectangle(original, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)
        cv2.imshow('original', original)
        show_on_tkinter(face, title=i + 1)
cv2.destroyAllWindows()
conn.close()

# 训练人脸识别器
recognizer = cv2.face.LBPHFaceRecognizer_create()
ids = []
faces = []
for name in pathlib.Path('dataset').rglob('*'):
    images = pathlib.Path(name).glob('*')
    for image in images:
        ids.append(name_id_map[name.name])
        image = Image.open(image).convert('L')
        image = np.array(image)
        faces.append(image)
ids = np.array(ids)
recognizer.train(faces, ids)
recognizer.save('recognizer.yml')  # 保存人脸识别器模型

# 使用人脸识别器


recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('recognizer.yml')  # 加载人脸识别器
img = cv2.imread('image/2.jpg')  # 选一张图片识别
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = model.detectMultiScale(gray)
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)
    ids, conf = recognizer.predict(gray[y:y + h, x:x + w])
    name = id_name_map[ids]
    print(ids, name, conf)
    img = cv2_putChinese(img, name, (x + 2, y + h - 5))
cv2.imshow('result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('result.jpg', img)
print('已保存')

记录人脸

python人脸识别肤色人种 python 人脸_人脸识别_18

效果

python人脸识别肤色人种 python 人脸_python_19


2. OpenFace人脸识别器(尚未完成)

OpenFace官网

Face Recognition using OpenFace


3. DeepID人脸识别器(尚未完成)


4. FaceNet人脸识别器(尚未完成)

使用 FaceNet 的 人脸识别预训练模型,模型基于 Inception ResNet v1,在2018年上传。

随意选一个模型:

  • LFW准确率:99.05%
  • 训练数据集:CASIA-WebFace
  • LFW准确率:99.65%
  • 训练数据集:VGGFace2

Train a classifier on own images · davidsandberg/facenet Wiki · GitHub


5. InsightFace(尚未完成)

开源大佬面对面:InsightFace带你打造开箱即用的人脸识别系统


6. ArcFace(尚未完成)


摄像头捕获

import cv2
import numpy as np

net = cv2.dnn.readNetFromTensorflow('opencv_face_detector_uint8.pb', 'opencv_face_detector.pbtxt')  # TensorFlow模型


def face_recognition(image):
    height, width, channel = image.shape  # 高、宽、通道数
    blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0))  # 调整大小并降低光照的影响
    net.setInput(blob)  # 设置输入
    detections = net.forward()  # 检测结果
    faces = detections[0, 0]  # 人脸结果
    for face in faces:
        confidence = face[2]  # 置信度
        if confidence > 0.5:  # 置信度阈值设为0.5
            box = face[3:7] * np.array([width, height, width, height])  # 人脸矩形框坐标
            pt1 = int(box[0]), int(box[1])  # 左上角坐标
            pt2 = int(box[2]), int(box[3])  # 右下角坐标
            cv2.rectangle(image, pt1, pt2, (0, 255, 0), thickness=2)  # 画出人脸矩形框

            text = '{:.2f}%'.format(confidence * 100)  # 置信度文本
            startX, startY = pt1
            y = startY - 10 if startY - 10 > 10 else startY + 10
            org = (startX, y)  # 文本的左下角坐标
            cv2.putText(image, text, org, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), thickness=2)  # 画出置信度
    return image


if __name__ == '__main__':
    cap = cv2.VideoCapture(0)  # 打开摄像头

    if not cap.isOpened():  # 没打开直接退出
        print("Cannot open camera")
        exit()

    while True:
        ret, frame = cap.read()  # 逐帧捕获
        if not ret:  # 正确读取ret为True
            print("Can't receive frame (stream end?). Exiting ...")
            break
        frame = face_recognition(frame)
        cv2.imshow('frame', frame)  # 显示
        if cv2.waitKey(1) == ord('q'):  # q退出
            break

    cap.release()  # 释放摄像头
    cv2.destroyAllWindows()

效果

python人脸识别肤色人种 python 人脸_计算机视觉_20


戴圣诞帽

图片尺寸会被统一,仍需优化

python人脸识别肤色人种 python 人脸_人脸识别_21

import cv2
import numpy
import random
from PIL import Image
from pathlib import Path

# 参数
HAT_PATH = './hat/'  # 圣诞帽图像路径
MODEL_PATH = 'haarcascade_frontalface_default.xml'  # 人脸识别预训练模型路径

# 读取
model = cv2.CascadeClassifier(MODEL_PATH)

# 读取圣诞帽
hats = []  # 圣诞帽
hats_portion = []  # 圣诞帽宽高比
for i in Path(HAT_PATH).glob('*.png'):
    hat = Image.open(i)
    width, height = hat.size
    hats.append(hat)
    hats_portion.append(width / height)


def std_size(imagePath):
    '''转标准尺寸'''
    pic = Image.open(imagePath)
    width, height = pic.size
    portion = width / height

    if portion < 1:  # 肖像
        if portion <= 0.75:
            pic_w = 960
            pic_h = round(960 / portion)
            box = (0, round((pic_h - 1280) / 2), 960, round(pic_h / 2 + 640))

        if portion > 0.75:
            pic_h = 1280
            pic_w = round(1280 * portion)
            box = (round((pic_w - 960) / 2), 0, round(pic_w / 2 + 480), 1280)

    elif portion > 1:  # 风景
        if portion >= 1.3333:
            pic_h = 960
            pic_w = round(960 * portion)
            box = (round((pic_w - 1280) / 2), 0, round(pic_w / 2 + 640), 960)

        if portion < 1.3333:
            pic_w = 1280
            pic_h = round(1280 / portion)
            box = (0, round((pic_h - 960) / 2), 1280, round(pic_h / 2 + 480))

    elif portion == 1:  # 正方形
        (pic_w, pic_h) = (960, 960)
        box = (0, 0, 960, 960)

    pic = pic.resize((pic_w, pic_h))
    pic = pic.crop(box)
    return pic


def face_detect(pil_image):
    '''人脸检测

    :param pil_image: PIL读取的图片
    '''
    image = cv2.cvtColor(numpy.array(pil_image), cv2.COLOR_RGB2BGR)  # PIL转cv
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = model.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=5,
        minSize=(50, 60),
        flags=cv2.CASCADE_SCALE_IMAGE
    )
    return faces


def get_hat(x, y, w, h):
    # 设定每个帽子的概率
    num = random.randint(1, 100)
    if num in range(1, 17):
        hat_num, offset1, offset2, offset3 = (0, 1.2, .05, .67)  # hat1
    elif num in range(17, 33):
        hat_num, offset1, offset2, offset3 = (1, 1.3, -.4, .62)  # hat2
    elif num in range(33, 49):
        hat_num, offset1, offset2, offset3 = (2, .9, .05, .8)  # hat3
    elif num in range(91, 101):
        hat_num, offset1, offset2, offset3 = (3, 1.2, .05, .67)  # green hat
    elif num in range(49, 65):
        hat_num, offset1, offset2, offset3 = (4, 1.2, -.1, 1.2)  # jiao1
    elif num in range(65, 81):
        hat_num, offset1, offset2, offset3 = (5, 1, 0, 1.2)  # jiao2
    elif num in range(81, 91):
        hat_num, offset1, offset2, offset3 = (6, .9, .05, 1)  # tree

    hat_portion = hats_portion[hat_num]
    (hat_w, hat_h) = (int(w * offset1), int(w * offset1 / hat_portion))
    # print('hat size:', hat_w, hat_h)
    hatter = hats[hat_num].resize((hat_w, hat_h))

    (hat_x, hat_y) = (int(x + w * offset2), int(y - hat_h * offset3))
    hat_pos = (hat_x, hat_y)
    # print('hat at:', hat_x, hat_y)

    return (hatter, hat_pos)


def wear_hat(imagePath, output, show=False):
    '''戴圣诞帽

    :param imagePath: 图片路径
    :param output: 保存路径
    :param show: 是否显示中间过程
    :return:
    '''
    # 人脸检测
    image = std_size(imagePath)
    faces = face_detect(image)

    if show:
        temp_image = image.copy()

    # 戴圣诞帽
    for (x, y, w, h) in faces:
        # print('face at:', x, y, w, h)
        (hatter, hat_pos) = get_hat(x, y, w, h)
        image.paste(hatter, hat_pos, hatter)
    image.save(output)

    if show:
        # 原图
        temp_image = cv2.cvtColor(numpy.array(temp_image), cv2.COLOR_RGB2BGR)
        cv2.imshow('1', temp_image)
        cv2.waitKey(0)

        # 人脸检测框
        for (x, y, w, h) in faces:
            cv2.rectangle(temp_image, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)
        cv2.imshow('1', temp_image)
        cv2.waitKey(0)

        # 戴圣诞帽
        temp_image = Image.fromarray(cv2.cvtColor(temp_image, cv2.COLOR_BGR2RGB))
        for (x, y, w, h) in faces:
            (hatter, hat_pos) = get_hat(x, y, w, h)
            temp_image.paste(hatter, hat_pos, hatter)
        temp_image = cv2.cvtColor(numpy.array(temp_image), cv2.COLOR_RGB2BGR)  # PIL转cv
        cv2.imshow('1', temp_image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()


if __name__ == '__main__':
    wear_hat('2.jpg', 'result.jpg', show=True)


TODO

  1. 人脸识别:即认出谁是谁
  2. OpenVINO预训练模型

需要Intel的CPU

参考文献:

  1. How to use OpenVINO pre-trained models?
  2. Using Intel OpenVINO Pre-Trained Models


人脸识别常用数据集

数据集

图片数量

人脸数量

描述

LFW (Labeled Faces in the Wild)

13233

5749

人脸识别的基准数据集

YTF (YouTube Faces)

3425视频

1595

CALFW (Cross-Age LFW)

跨年龄

CPLFW (Cross-Pose LFW)

跨姿势

CFP (Celebrities in Frontal-Profile in the Wild)

7000

500

知名人物的前额,侧脸

AgeDB-30

12240

570

跨年龄人脸识别数据集

MegaFace

470万

672057

平均每人7张图片

IJB-C (IARPA Janus Benchmark C)

138000图+11000视频

FRVT (Face Recognition Vendor Test)

考虑精度、速度、存储、可靠性等

VGGFace

200万

2622

噪声较小,常作为训练模型的数据

VGGFace2

331万

9131

噪声较小,跨年龄、姿态、种族,常作为训练模型的数据

CASIA-WebFace

494414

10575

国内颇具盛名的人脸识别数据集




参考文献

  1. opencv haarcascades 预训练模型
  2. OpenCV Document
  3. wx-fancy-pic: 微信公众号服务,根据用户发来的照片自动生成海报或有趣的照片
  4. OpenCV4 DNN人脸检测
  5. OpenCV中支持的人脸检测方法整理与汇总
  6. MTCNN实时人脸检测网络详解
  7. OpenVINO Toolkit Intel’s Pre-Trained Models
  8. openface: Face recognition with deep neural networks.
  9. facenet: Face recognition using Tensorflow
  10. awesome-Face_Recognition
  11. FaceBoxes—官方开源CPU实时高精度人脸检测器
  12. OpenCV Face Recognition - PyImageSearch
  13. 人脸识别常用数据集介绍(附下载链接)及常用评估指标
  14. 人脸识别最新进展以及工业级大规模人脸识别实践探讨
  15. 格灵深瞳开源全球最大最干净的人脸识别数据集:Glint360K
  16. A full guide to face detection
  17. insightface/detection/RetinaFace