700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 利用OpenCV和Python一百行代码快速实现人脸检测和人脸识别

利用OpenCV和Python一百行代码快速实现人脸检测和人脸识别

时间:2018-07-21 09:32:45

相关推荐

利用OpenCV和Python一百行代码快速实现人脸检测和人脸识别

利用OpenCV和Python一百行代码快速实现人脸检测和人脸识别

目录

利用OpenCV和Python一百行代码快速实现人脸检测和人脸识别1、前言2、准备工作3、OpenCV DNN模块式使用步骤

本章博客涉及代码和模型文件,关注以下公众号,回复关键字pycv人脸识别获取下载链接!

1、前言

在的时候,我写过一篇人脸检测和识别的博客,当时对关于人脸的图像识别还没有什么概念,就纯粹是跟上网上的教程做的一个记录,识别方式是利用的SVM(支持向量机)实现的,用的opencv版本为3.0.0,具体可看这里:Opencv人脸识别学习记录。

现如今图像类的识别都开始转型为使用深度学习方式,本文主要是利用opencv中的DNN模块,在4.5.4版本中并入了这位大神的人脸识别算法,识别精度和速度非常可观,源代码见这里:/ShiqiYu/libfacedetection

基于深度学习的人脸识别基本上分为两步完成,第一步是人脸检测与对齐;第二步是人脸特征提取与比对。

开发环境说明

截止3月14日,python版opencv最新版本为4.5.5.64,本博客使用的就是该版本python3.9PyCharm.2

pip安装opencv:

pip install opencv-python==4.5.5.64 -i https://pypi.tuna./simple

2、准备工作

模型下载:

人脸检测模型下载地址:/ShiqiYu/libfacedetection.train/tree/master/tasks/task1/onnx

人脸识别模型下载地址:/file/d/1ClK9WiB492c5OZFKveF3XiHCejoOxINW/view

opencv官方例程:

opencv官方人脸检测识别demo(python代码):/opencv/opencv/blob/4.x/samples/dnn/face_detect.py

opencv官方人脸检测识别demo(C++代码):/opencv/opencv/blob/4.x/samples/dnn/face_detect.cpp

除去参考官方的代码,还参考了这位大神的文章:https://mp./s/VijOXz4NEP3rRCM44Sd2pA

3、OpenCV DNN模块式使用步骤

首先读入图像并加载人脸检测和人脸识别模型:

import numpy as npimport cv2# 读入人脸图像image1 = cv2.imread('1.png')image2 = cv2.imread('2.png')input_shape = (300, 300)# 重塑图片为300X300大小image1 = cv2.resize(image1, input_shape)image2 = cv2.resize(image2, input_shape)# 加载人脸检测模型faceDetector = cv2.FaceDetectorYN_create(model='yunet.onnx', config='', input_size=input_shape)# 加载人脸识别模型faceRecognizer = cv2.FaceRecognizerSF_create(model='face_recognizer_fast.onnx', config='')

然后对图片进行人脸检测:

face1_detect = faceDetector.detect(image1)face2_detect = faceDetector.detect(image2)

face1_detect返回的是一个二维的元组类型,第一纬是识别到的人脸个数,第二纬是一个二维的数组,表示的人脸坐标数据,每一个人脸坐标数据大小为15个数,其中包括:

人脸XY坐标及宽度(4个数)右眼瞳孔XY坐标(2个数)左眼瞳孔XY坐标(2个数)鼻尖XY坐标(2个数)右嘴角XY坐标(2个数)左嘴角XY坐标(2个数)置信度(1个数,越接近1说明与人脸越像)

所以你可以这么做来查看是否发现了人脸:

if face1_detect[1] is None or face2_detect[1] is None:print('------ 未发现人脸!')exit(0)

把检测到的人脸画出来:

faces_detect = (face1_detect[1], face2_detect[1])images = (image1, image2)# 框出人脸并画出人脸的关键点for i in range(len(images)):for face_index, face_coords in enumerate(faces_detect[i]):thickness = 2# 准确度accuracy = face_coords[-1]# 坐标转成int类型coords = face_coords[:-1].astype(np.int32)# 框出人脸cv2.rectangle(images[i], (coords[0], coords[1]), (coords[0] + coords[2], coords[1] + coords[3]), (0, 255, 0), thickness)# 画出左右瞳孔、左右嘴角、鼻尖的位置cv2.circle(images[i], (coords[4], coords[5]), 2, (255, 0, 0), thickness)cv2.circle(images[i], (coords[6], coords[7]), 2, (0, 0, 255), thickness)cv2.circle(images[i], (coords[8], coords[9]), 2, (0, 255, 0), thickness)cv2.circle(images[i], (coords[10], coords[11]), 2, (255, 0, 255), thickness)cv2.circle(images[i], (coords[12], coords[13]), 2, (0, 255, 255), thickness)# 显示准确度cv2.putText(images[i], 'The accuracy of: {:.2f}'.format(accuracy), (1, 16), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)# 显示图片cv2.imshow('image{:d}'.format(i), images[i])

接下来是人脸对齐:

# 人脸对齐,alignCrop返回的是人脸图像face1_align = faceRecognizer.alignCrop(image1, face1_detect[1])face2_align = faceRecognizer.alignCrop(image1, face2_detect[1])

然后提取128纬度的特征向量,用于下一步的人脸对比识别:

face1_feature = faceRecognizer.feature(face1_align)face2_feature = faceRecognizer.feature(face2_align)

再然后进行人脸对比识别,判断是否是同一个人:

cosine_similarity_threshold = 0.363l2_similarity_threshold = 1.128# 人脸识别(余弦匹配方式)cosine_score = faceRecognizer.match(face1_feature, face2_feature, cv2.FaceRecognizerSF_FR_COSINE)# 人脸识别(L2匹配方式)l2_score = faceRecognizer.match(face1_feature, face2_feature, cv2.FaceRecognizerSF_FR_NORM_L2)msg = '不是同一个人'if cosine_score >= cosine_similarity_threshold:msg = '是同一个人'print('------ 两张人脸图像%s!余弦阈值:%0.3f,余弦值:%0.3f。(注:余弦值越高表示相似度越高,最大值为1.0)' % (msg, cosine_similarity_threshold, cosine_score))msg = '不是同一个人'if l2_score <= l2_similarity_threshold:msg = '是同一个人'print('------ 两张人脸图像%s!L2距离:%0.3f,阈值:%0.3f。(注:L2距离越低表示相似度越高,最小值为0.0)' % (msg, l2_score, l2_similarity_threshold))cv2.waitKey()

我特意找了小李子一个年轻时候和一个上了年纪的两张照片进行人脸检测和识别,运行效果如下:

可以看出,人脸检测的结果是非常准的,同时也能够正确的识别出是同一个人!

ends…

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。