windows insightface库 人脸识别入门教程

初学insightface,在网上找了几天的博客,但是大多都是在Linux上运行的教程。而且我下的源代码跟他们的结构完全不一样,一度怀疑自己下错了。后来发现是因为作者一直在迭代更新,到现在跟之前已经有很大不同了。为了便于自己入门,所以我去github上下载了作者19年的版本。

环境配置

环境配置按照https://zhuanlan.zhihu.com/p/33750684所说就行,cuda10.1也可以运行。

源码下载

https://github.com/deepinsight/insightface#test-on-megaface
可以找19年的版本,能看懂也可以直接用新的。

库目录

我下载下来的库文件如图,版本不同会有小差别,大致差不多就行。
在这里插入图片描述

之后的操作都是再deploy目录中进行的。

模型下载

在网盘中下载好模型
https://pan.baidu.com/s/1jKahEXw
下载好后放在models文件夹中
在这里插入图片描述
之后就可以在deploy目录下的test.py中进行人脸识别了。

路径配置

在这里插入图片描述
里面会有一些红线是不用管的。

在这里插入图片描述
之后是路径的配置,将你模型的路径填进去,还有存放人脸特征的路径,由于我做的视频的人脸识别,所以最后是视频的路径。

在这里插入图片描述
之后可以通过这些方式进行调用。

人脸识别

人脸识别的工作原理是用检测到的人脸输入进模型,得到特征值后,与特征库中的人脸数据进行对比,计算它与特征库中每个数据的距离。之后取距离最短的一个数据的标签作为该人脸的识别结果。所以需要先进行人脸特征的持久化,之后进行人脸识别操作。

人脸特征持久化

import face_model
import argparse
import cv2
import sys
import numpy as np
import os


parser = argparse.ArgumentParser(description='face model test')
# general
parser.add_argument('--image-size', default='112,112', help='')
parser.add_argument('--model', default='../models/model-r50-am-lfw/model,0', help='path to load model.')
parser.add_argument('--ga-model', default='', help='path to load model.')
parser.add_argument('--gpu', default=0, type=int, help='gpu id')
parser.add_argument('--det', default=0, type=int, help='mtcnn option, 1 means using R+O, 0 means detect from begining')
parser.add_argument('--flip', default=0, type=int, help='whether do lr flip aug')
parser.add_argument('--threshold', default=1.24, type=float, help='ver dist threshold')
parser.add_argument('--binPath', default='myfeature')
parser.add_argument('--videoPath', default='video/test.mp4')
args = parser.parse_args()


videoPath = args.videoPath
binPath = args.binPath
threshold = float(args.threshold)

feature = []
label = []
# model = face_model_v2.FaceModel(args)
#查看是否存在路径,没有则创建
if not os.path.exists(binPath):
    os.makedirs(binPath)
#调用模型
model = face_model.FaceModel(args)
#遍历路径中的图片,将他们的名字保存到label
for s in os.listdir('imgs'):
    img = cv2.imread('imgs/'+s)
    img = model.get_input(img)
    f1 = model.get_feature(img)
    f1.tofile('myfeature/%s.bin'%s.split('.')[0])


运行后可以得到bin文件在这里插入图片描述

图片人脸识别

计算两个人脸的距离代码:

# 查找当前特征最接近的特征
def findNear(feature, f, threshold, label):
    dist_list = []
    # 遍历特征库
    for feature_unit in feature:
        # 距离的定义是(特征1-特征2)开根号并求和
        dist = np.sum(np.square(feature_unit - f))
        # dist_list作用是将所有距离都保存下来,以便获得最小距离
        dist_list.append(dist)
        # 寻找到最小距离
    minDist = np.min(dist_list)
    print(minDist)
    # 如果最小距离小于等于阈值
    if minDist <= threshold:
        # 求出最小距离对应的索引
        minIdx = np.argmin(dist_list)
        # 找到姓名
        print(label[minIdx])
		#返回姓名和概率
        return label[minIdx],(threshold-minDist)/threshold
    else:
        # 如果没有满足条件的,就返回'none'
        return 'none',0

在进行识别之前修改一下face_model.py中的部分代码,因为源代码每次只能检测一张人脸,在建立人脸特征库时够用,但进行人脸检测时照片里不止一个人,因此需要做一些修改。
复制粘贴face_model.py,将名字改为Face_model_v2.py.
之后修改其中的get_input的方法。

  # 主要修改get_input方法
  def get_input(self, face_img):
    # print('into face_model_v2')
    ret = self.detector.detect_face(face_img, det_type=self.args.det)
    if ret is None:
      return None
    bbox, points = ret
    # 存放所有检测的人脸图像
    aligned_list = []
    # 存放所有人脸坐标
    bbox_list = []
    if bbox.shape[0] == 0:
      return None
    for i in range(bbox.shape[0]):
      # 获取每一个坐标
      bbox_ = bbox[i, 0:4]
      # 存放坐标
      bbox_list.append(bbox_)
      # 获取每一个特征点
      points_ = points[i, :].reshape((2, 5)).T
      nimg = face_preprocess.preprocess(face_img, bbox_, points_, image_size='112,112')
      nimg = cv2.cvtColor(nimg, cv2.COLOR_BGR2RGB)
      aligned = np.transpose(nimg, (2, 0, 1))
      # 存放坐标
      aligned_list.append(aligned)
    return aligned_list, bbox_list

修改完后记得将之前持久化导入的模型改为

model = face_model_v2.FaceModel(args)

照片人脸识别代码:

# 遍历目录获得目录中文件名字作为label,文件内容加入feature
for bin_ in os.listdir(binPath):
    # 注意要指定dtype
    feature.append(np.fromfile(binPath + '/' + bin_, dtype=np.float32))
    label.append(bin_.split('.')[0])

img=cv2.imread('hezhao.jpg')
# img=cv2.resize(img,(500,500))
imgs, bbox = model.get_input(img)
for img_unit, bbox_unit in zip(imgs, bbox):
    if img_unit.shape:
        # 获得特征
        f = model.get_feature(img_unit)
        # 找到匹配信息
        res,dist = findNear(feature, f, threshold, label)
        # 如果匹配到了姓名
        if res != 'none':
            # 用方框标注,bbox_unit中的值为(左,上,右,下)
            # 按照cv2.rectangle的参数写入
            cv2.rectangle(img, (int(bbox_unit[0]), int(bbox_unit[1])),
                          (int(bbox_unit[2]), int(bbox_unit[3])), (0, 0, 255))
            # 标记文字到图像中,参数:图像,文字,位置,字体,大小,颜色,宽度
            img = cv2.putText(img, res+"%.2f"%float(dist), (int(bbox_unit[0])-2, int(bbox_unit[1])),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
cv2.imshow('name',img)
cv2.waitKey(0)

用博主的自拍测试了下
在这里插入图片描述
之后用合照测试:
在这里插入图片描述
总的代码:

import face_model_v2
import face_model
import argparse
import cv2
import sys
import numpy as np
import os


parser = argparse.ArgumentParser(description='face model test')
# general
parser.add_argument('--image-size', default='112,112', help='')
parser.add_argument('--model', default='../models/model-r50-am-lfw/model,0', help='path to load model.')
parser.add_argument('--ga-model', default='', help='path to load model.')
parser.add_argument('--gpu', default=0, type=int, help='gpu id')
parser.add_argument('--det', default=0, type=int, help='mtcnn option, 1 means using R+O, 0 means detect from begining')
parser.add_argument('--flip', default=0, type=int, help='whether do lr flip aug')
parser.add_argument('--threshold', default=1.24, type=float, help='ver dist threshold')
parser.add_argument('--binPath', default='myfeature')
parser.add_argument('--videoPath', default='video/test.mp4')
args = parser.parse_args()


videoPath = args.videoPath
binPath = args.binPath
threshold = float(args.threshold)

feature = []
label = []
model = face_model_v2.FaceModel(args)
#查看是否存在路径,没有则创建
# if not os.path.exists(binPath):
#     os.makedirs(binPath)
#调用模型
# model = face_model.FaceModel(args)
# 遍历路径中的图片,将他们的名字保存到label
# for s in os.listdir('imgs'):
#     img = cv2.imread('imgs/'+s)
#     img,_ = model.get_input(img)
#     f1 = model.get_feature(img)
#     f1.tofile('myfeature/%s.bin'%s.split('.')[0])

# 查找当前特征最接近的特征
def findNear(feature, f, threshold, label):
    dist_list = []
    # 遍历特征库
    for feature_unit in feature:
        # 距离的定义是(特征1-特征2)开根号并求和
        dist = np.sum(np.square(feature_unit - f))
        # dist_list作用是将所有距离都保存下来,以便获得最小距离
        dist_list.append(dist)
        # 寻找到最小距离
    minDist = np.min(dist_list)
        # 如果最小距离小于等于阈值
    if minDist <= threshold:
        # 求出最小距离对应的索引
        minIdx = np.argmin(dist_list)
        # 找到姓名
        return label[minIdx]
    else:
        # 如果没有满足条件的,就返回'none'
        return 'none'


# 遍历目录获得目录中文件名字作为label,文件内容加入feature
for bin_ in os.listdir(binPath):
    # 注意要指定dtype
    feature.append(np.fromfile(binPath + '/' + bin_, dtype=np.float32))
    label.append(bin_.split('.')[0])


# 查找当前特征最接近的特征
def findNear(feature, f, threshold, label):
    dist_list = []
    # 遍历特征库
    for feature_unit in feature:
        # 距离的定义是(特征1-特征2)开根号并求和
        dist = np.sum(np.square(feature_unit - f))
        # dist_list作用是将所有距离都保存下来,以便获得最小距离
        dist_list.append(dist)
        # 寻找到最小距离
    minDist = np.min(dist_list)
    print(minDist)
    # 如果最小距离小于等于阈值
    if minDist <= threshold:
        # 求出最小距离对应的索引
        minIdx = np.argmin(dist_list)
        # 找到姓名
        print(label[minIdx])

        return label[minIdx],(threshold-minDist)/threshold
    else:
        # 如果没有满足条件的,就返回'none'
        return 'none',0


img=cv2.imread('hezhao.jpg')
# img=cv2.resize(img,(500,500))
imgs, bbox = model.get_input(img)
for img_unit, bbox_unit in zip(imgs, bbox):
    if img_unit.shape:
        # 获得特征
        f = model.get_feature(img_unit)
        # 找到匹配信息
        res,dist = findNear(feature, f, threshold, label)
        # 如果匹配到了姓名
        if res != 'none':
            # 用方框标注,bbox_unit中的值为(左,上,右,下)
            # 按照cv2.rectangle的参数写入
            cv2.rectangle(img, (int(bbox_unit[0]), int(bbox_unit[1])),
                          (int(bbox_unit[2]), int(bbox_unit[3])), (0, 0, 255))
            # 标记文字到图像中,参数:图像,文字,位置,字体,大小,颜色,宽度
            img = cv2.putText(img, res+"%.2f"%float(dist), (int(bbox_unit[0])-2, int(bbox_unit[1])),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
cv2.imshow('name',img)
cv2.waitKey(0)

视频人脸识别

关于视频的人脸识别可以看参考文章中的博客,里面已经很详细了。

参考文章:

https://blog.csdn.net/xiaotuzigaga/article/details/89224594

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
抱歉,我是一个语言模型AI,无法编写和运行代码。不过,以下是用insightface实现人脸识别的一般步骤: 1. 安装insightface ``` pip install insightface ``` 2. 下载人脸检测模型和人脸识别模型 ``` import os import urllib model_urls = [ 'https://github.com/deepinsight/insightface/blob/master/models/model-r100-ii/model-0000.params?raw=true', 'https://github.com/deepinsight/insightface/blob/master/models/model-r100-ii/model-0000.params?raw=true', 'https://github.com/deepinsight/insightface/blob/master/models/retinaface/R50/retinaface-R50.zip?raw=true' ] model_names = [ 'model-r100-ii/model-0000.params', 'model-r100-ii/model-symbol.json', 'retinaface-R50/model' ] for url, name in zip(model_urls, model_names): if not os.path.exists(name): print('Downloading', name) urllib.request.urlretrieve(url, name) ``` 3. 加载人脸检测模型和人脸识别模型 ``` from insightface import model_zoo from insightface.model_zoo import get_model detector = get_model('retinaface_r50_v1') detector.prepare(ctx_id=-1, nms=0.4) recognition = get_model('arcface_r100_v1') recognition.prepare(ctx_id=-1) ``` 4. 加载人脸 ``` import cv2 face_db = {} for file in os.listdir('faces'): name = os.path.splitext(file)[0] img = cv2.imread(os.path.join('faces', file)) embedding = recognition.get_embedding(img) face_db[name] = embedding ``` 5. 进行人脸识别 ``` img = cv2.imread('test.jpg') faces = detector.detect(img) for face in faces: embedding = recognition.get_embedding(face) min_distance = float('inf') min_name = None for name, db_embedding in face_db.items(): distance = recognition.get_distance(embedding, db_embedding) if distance < min_distance: min_distance = distance min_name = name if min_name is not None and min_distance < 0.8: cv2.rectangle(img, (face[0], face[1]), (face[2], face[3]), (0, 255, 0), 2) cv2.putText(img, min_name, (face[0], face[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) else: cv2.rectangle(img, (face[0], face[1]), (face[2], face[3]), (0, 0, 255), 2) cv2.putText(img, 'Unknown', (face[0], face[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2) cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 以上步骤仅供参考,实际使用时需要根据具体情况进行调整和优化。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值