前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于insightface实现的人脸识别和人脸注册

基于insightface实现的人脸识别和人脸注册

作者头像
夜雨飘零
修改2023-06-04 16:34:45
4.1K0
修改2023-06-04 16:34:45
举报
文章被收录于专栏:CSDN博客CSDN博客

本教程的人脸识别是使用的是insightface库进行开发的,该库使用的框架为mxnet。

安装环境

  1. 安装mxnet,支持1.3~1.6版本,安装命令如下。
代码语言:javascript
复制
pip install mxnet-cu101==1.5.1
  1. 安装insightface,命令如下。
代码语言:javascript
复制
pip install --upgrade insightface
  1. 安装其他依赖库。
代码语言:javascript
复制
pip install flask flask-cors PyYAML scikit-learn opencv-python

人脸识别和人脸注册

为了方便参数的修改,使用yaml格式进行配置参数,yaml格式文件加载如下。

代码语言:javascript
复制
import os
import yaml
import numpy as np
import insightface
from random import choice
import cv2
from sklearn import preprocessing


# Deploy Configuration File Parser
class DeployConfig:
    def __init__(self, conf_file):
        if not os.path.exists(conf_file):
            raise Exception('Config file path [%s] invalid!' % conf_file)

        with open(conf_file) as fp:
            configs = yaml.load(fp, Loader=yaml.FullLoader)
            deploy_conf = configs["FACE"]
            # 正数为GPU的ID,负数为使用CPU
            self.gpu_id = deploy_conf["GPU_ID"]
            self.face_db = deploy_conf["FACE_DB"]
            self.threshold = deploy_conf["THRESHOLD"]
            self.nms = deploy_conf["NMS"]

config.yaml内容如下:

代码语言:javascript
复制
FACE:
  GPU_ID: 0
  FACE_DB: "face_db"
  THRESHOLD: 1.24
  NMS: 0.50

然后开始编写人脸识别和人脸注册工具类,使用insightface.app.FaceAnalysis()可以获取模型对象,这里包含了三个模型,首先是人脸检测模型,然后是人脸特征提取模型,和最后的性别年龄识别模型。使用model.prepare()可以配置ctx_id指定使用哪一块GPU,如果是负数则是使用CPU执行预测,nms配置的是人脸检测的阈值。load_faces()函数是加载人脸库中的人脸,用于之后的人脸识别对比。

代码语言:javascript
复制
class FaceRecognition:
    def __init__(self, conf_file):
        self.config = DeployConfig(conf_file)
        # 加载人脸识别模型
        self.model = insightface.app.FaceAnalysis()
        self.model.prepare(ctx_id=self.config.gpu_id, nms=self.config.nms)
        # 人脸库的人脸特征
        self.faces_embedding = list()
        # 加载人脸库中的人脸
        self.load_faces(self.config.face_db)

    # 加载人脸库中的人脸
    def load_faces(self, face_db_path):
        if not os.path.exists(face_db_path):
            os.makedirs(face_db_path)
        for root, dirs, files in os.walk(face_db_path):
            for file in files:
                input_image = cv2.imdecode(np.fromfile(os.path.join(root, file), dtype=np.uint8), 1)
                user_id = file.split(".")[0]
                face = self.model.get(input_image)[0]
                embedding = np.array(face.embedding).reshape((1, -1))
                embedding = preprocessing.normalize(embedding)
                self.faces_embedding.append({
                    "user_id": user_id,
                    "feature": embedding
                })

接下来编写recognition()函数实现人脸识别,通过调用model.get()函数可以获取图像中每张人脸的位置bbox,人脸关键点landmark,人脸特征embedding,性别gender,年龄age。其中使用人脸识别的就是通过欧氏距离来对比人脸库中的人脸特征,默认如何它们的欧氏距离小于1.24,我们就可以认为他们是同一个人。

代码语言:javascript
复制
    def recognition(self, image):
        faces = self.model.get(image)
        results = list()
        for face in faces:
            result = dict()
            # 获取人脸属性
            result["bbox"] = np.array(face.bbox).astype(np.int32).tolist()
            result["landmark"] = np.array(face.landmark).astype(np.int32).tolist()
            result["age"] = face.age
            gender = '男'
            if face.gender == 0:
                gender = '女'
            result["gender"] = gender
            # 开始人脸识别
            embedding = np.array(face.embedding).reshape((1, -1))
            embedding = preprocessing.normalize(embedding)
            result["user_id"] = "unknown"
            for com_face in self.faces_embedding:
                r = self.feature_compare(embedding, com_face["feature"], self.config.threshold)
                if r:
                    result["user_id"] = com_face["user_id"]
            results.append(result)
        return results

上面使用到的欧氏距离计算方式如下。

代码语言:javascript
复制
    @staticmethod
    def feature_compare(feature1, feature2, threshold):
        diff = np.subtract(feature1, feature2)
        dist = np.sum(np.square(diff), 1)
        if dist < threshold:
            return True
        else:
            return False

人脸注册方式如下,通过传入一张照片,首先要判断照片中的人脸只有一张,然后开始提取该人脸的特征值,再次比较要注册的人脸是否已经存在人脸库中了,否之就包人脸特征添加到人脸库中并保存图片到本地。通过命名包只包含一个人脸的图片放在face_db文件夹中也可以实现。

代码语言:javascript
复制
    def register(self, image):
        faces = self.model.get(image)
        if len(faces) != 1:
            return None
        # 判断人脸是否存在
        embedding = np.array(faces[0].embedding).reshape((1, -1))
        embedding = preprocessing.normalize(embedding)
        is_exits = False
        for com_face in self.faces_embedding:
            r = self.feature_compare(embedding, com_face["feature"], self.config.threshold)
            if r:
                is_exits = True
        if is_exits:
            return None
        old_user_id = [d["user_id"] for d in self.faces_embedding]
        user_id = self.get_user_id(old_user_id)
        # 符合注册条件保存图片,同时把特征添加到人脸特征库中
        cv2.imencode('.png', image)[1].tofile(os.path.join(self.config.face_db, '%s.png' % user_id))
        self.faces_embedding.append({
            "user_id": user_id,
            "feature": embedding
        })
        return user_id
        
    def get_user_id(self, old_user_id):
	    print(old_user_id)
	    while True:
	        user_id = "".join([choice("0123456789ABCDEF") for i in range(8)])
	        if user_id not in old_user_id:
	            break
	    return user_id

使用

全部功能都实现了,使用如下,首先是进行人脸注册,注册成功之后会获得一个用户注册ID,之后的人脸识别可以用过这个用户ID判断是不是这个人。

代码语言:javascript
复制
if __name__ == '__main__':
    img = cv2.imread("test.png")
    face_recognitio = FaceRecognition("config.yml")
    user_id = face_recognitio.register(img)
    print(user_id)

人脸识别,通过传入一张图片,可以输出每张人脸对应的用户ID、人脸位置bbox,人脸关键点landmark,性别gender,年龄age。

代码语言:javascript
复制
if __name__ == '__main__':
    img = cv2.imread("test2.png")
    face_recognitio = FaceRecognition("config.yml")
    result = face_recognitio.recognition(img)
    print(result)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装环境
  • 人脸识别和人脸注册
  • 使用
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档