百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

总结几个简单好用的Python人脸识别算法

off999 2024-10-20 08:08 23 浏览 0 评论

哈喽,大家好。

今天给大家总结几个简单、好用的人脸识别算法。 人脸识别是计算机视觉中比较常见的技术,生活中,我们接触最多的人脸识别场景是人脸考勤,我之前还专门写过一篇人脸考勤的项目,感兴趣的朋友可以看看。

人脸识别的算法最核心的工作是从一张图片中识别出人脸的位置。识别的算法可以说是多种多样, 下面我就来为大家一一介绍下。



1. HoG人脸检测

该算法采用传统的机器学习算法来识别人脸。传统机器学习算法的特点是人工构造特征,然后将构造好的特征送入模型训练。

该算法用HoG提取图片中人脸特征,用SVM算法进行分类。

HoG(Histogram of Oriented Gradient, 方向梯度直方图)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子,通过计算和统计图像局部区域的梯度方向直方图来构成特征。

dlib库中有该算法的实现,下面我们看看核心代码

import dlib
# 加载预训练的 HoG 人脸检测器
hog_face_detector = dlib.get_frontal_face_detector()

# 对图片进行人脸检测
results = hog_face_detector(imgRGB, 0)

for bbox in results:
  x1 = bbox.left()  # 人脸左上角x坐标
  y1 = bbox.top()  # 人脸左上角y坐标
  x2 = bbox.right()  # 人脸右下角x坐标
  y2 = bbox.bottom()  # 人脸右下角y坐标

results 存放一张图中检测出来的多个人脸, 遍历results可以得到每张人脸的矩形框。

检测示例如下:

绿框框出来的就是算法检测出来的人脸。

HoG 人脸检测由于采用传统机器学习算法,所以性能比较高,在CPU上运行也可以比较快。但它无法检测小于 80*80 的人脸,对旋转人脸、非正面人脸,识别效果也不太好。

2. 深度学习人脸检测

虽然传统机器学习算法检测更快,但准确度却有待提升。基于深度学习的人脸检测算法往往会更加准确。

这里介绍的是使用残差网络ResNet-10通过网络(模型)在图像的单通道( Single Shot Detector,SSD)中检测多个人脸。简称SSD算法。

首先,需要将原始图片进行blob预处理,然后直接送入模型,进行检测

cv2库提供了该算法的实现,核心代码如下:

import cv2

# 加载预训练的 SSD 模型
opencv_dnn_model = cv2.dnn.readNetFromCaffe(
      prototxt="models/deploy.prototxt"
      , caffeModel="models/res10_300x300_ssd_iter_140000_fp16.caffemodel")

# 原始图片 blob 处理
preprocessed_image = cv2.dnn.blobFromImage(image, scalefactor=1.0, size=(300, 300), mean=(104.0, 117.0, 123.0), swapRB=False, crop=False)
 
# blob 图片送入模型
opencv_dnn_model.setInput(preprocessed_image)

# 模型推理,进行人脸检测
results = opencv_dnn_model.forward()  

# 遍历人脸
for face in results[0][0]:
  # 置信度
  face_confidence = face[2]
  
  # 人脸边框的左上角和右下角坐标点
  x1 = int(bbox[0] * image_width)
  y1 = int(bbox[1] * image_height)
  x2 = int(bbox[2] * image_width)
  y2 = int(bbox[3] * image_height)

results[0][0]存放了检测出来的多张人脸,每张人脸用数组表达,数组的第3位存放置信度,可以通过阈值过滤不置信的人脸。数组的第4~7位存放检测出来的人脸矩形框左上角和右下角的坐标。

相比于 HoG 人脸检测,SSD 算法对遮挡、非正面人脸也能检测出来。



3. 卷积神经网络人脸检测

卷积就不多说了,了解计算机视觉的都知道。

dlib库提供了卷积神经网络人脸检测算法的实现,用法跟之前类似

import dlib

# 记载预训练模型
cnn_face_detector = dlib.cnn_face_detection_model_v1("models/mmod_human_face_detector.dat")

# 人脸检测
results = cnn_face_detector(imgRGB, 0)

# 遍历每张人脸
for face in results:
  # 人脸边框      
  bbox = face.rect
  
  # 人脸边框的左上角和右下角坐标点
  x1 = int(bbox.left() * (width/new_width))
  y1 = int(bbox.top() * (height/new_height))
  x2 = int(bbox.right() * (width/new_width))
  y2 = int(bbox.bottom() * (height/new_height))

results的解析跟上面类似,这里就不在赘述了。

采用卷积神经网络的人脸检测算法优势很明显,比前两个更准确和健壮,并且还能够检测遮挡下的人脸。

即便非正面、且光线暗的图片,也能很好检测出来

但该算法相应的缺点也很明显,检测过程所花费的时间非常长,无法在 CPU 上实时运行。

4. BlazeFace

上面的算法要么精度高、速度慢,要么速度快,精度低。那有没有一种检测算法,既有高准确率,又有高性能呢?

答案是肯定的,BlazeFace是一种非常轻量级且高度准确的人脸检测器,号称亚毫秒级的人脸检测器。其灵感来自 Single Shot MultiBox Detector (SSD)MobileNetv2

Mediapipe库提供了该算法的实现,核心代码如下:

import mediapipe as mp

# 画图工具
mp_drawing = mp.solutions.drawing_utils

# 初始化人脸检测模型
mp_face_detection = mp.solutions.face_detection
mp_face_detector = mp_face_detection.FaceDetection(min_detection_confidence=0.4)

results = mp_face_detector.process(imgRGB)

if results.detections:

  # 变脸检测出的人脸
  for face_no, face in enumerate(results.detections):

      # 画人脸关键点
      mp_drawing.draw_detection(image=output_image, detection=face, keypoint_drawing_spec=mp_drawing.DrawingSpec(color=(0,255,0),thickness=-1, circle_radius=image_width//115), bbox_drawing_spec=mp_drawing.DrawingSpec(color=(0,255,0),thickness=image_width//180))

      # 画人脸框
      face_bbox = face.location_data.relative_bounding_box
      x1 = int(face_bbox.xmin*image_width)
      y1 = int(face_bbox.ymin*image_height)

      cv2.rectangle(output_image, pt1=(x1, y1-image_width//20), pt2=(x1+image_width//16, y1), color=(0, 255, 0), thickness=-1)

效果如下:

可以看到,BlazeFace算法不光能检测人脸,还能识别出人脸6个关键点(眼睛、鼻子、耳朵、嘴)。

上面就是今天分享的4个人脸识别的算法。

识别出人脸,我们再做人脸考勤就非常简单了,把人脸Embedding成向量,计算向量的之间的距离即可。

文章来自https://www.cnblogs.com/duma/p/16487643.html

相关推荐

面试官:来,讲一下枚举类型在开发时中实际应用场景!

一.基本介绍枚举是JDK1.5新增的数据类型,使用枚举我们可以很好的描述一些特定的业务场景,比如一年中的春、夏、秋、冬,还有每周的周一到周天,还有各种颜色,以及可以用它来描述一些状态信息,比如错...

一日一技:11个基本Python技巧和窍门

1.两个数字的交换.x,y=10,20print(x,y)x,y=y,xprint(x,y)输出:102020102.Python字符串取反a="Ge...

Python Enum 技巧,让代码更简洁、更安全、更易维护

如果你是一名Python开发人员,你很可能使用过enum.Enum来创建可读性和可维护性代码。今天发现一个强大的技巧,可以让Enum的境界更进一层,这个技巧不仅能提高可读性,还能以最小的代价增...

Python元组编程指导教程(python元组的概念)

1.元组基础概念1.1什么是元组元组(Tuple)是Python中一种不可变的序列类型,用于存储多个有序的元素。元组与列表(list)类似,但元组一旦创建就不能修改(不可变),这使得元组在某些场景...

你可能不知道的实用 Python 功能(python有哪些用)

1.超越文件处理的内容管理器大多数开发人员都熟悉使用with语句进行文件操作:withopen('file.txt','r')asfile:co...

Python 2至3.13新特性总结(python 3.10新特性)

以下是Python2到Python3.13的主要新特性总结,按版本分类整理:Python2到Python3的重大变化Python3是一个不向后兼容的版本,主要改进包括:pri...

Python中for循环访问索引值的方法

技术背景在Python编程中,我们经常需要在循环中访问元素的索引值。例如,在处理列表、元组等可迭代对象时,除了要获取元素本身,还需要知道元素的位置。Python提供了多种方式来实现这一需求,下面将详细...

Python enumerate核心应用解析:索引遍历的高效实践方案

喜欢的条友记得关注、点赞、转发、收藏,你们的支持就是我最大的动力源泉。根据GitHub代码分析统计,使用enumerate替代range(len())写法可减少38%的索引错误概率。本文通过12个生产...

Python入门到脱坑经典案例—列表去重

列表去重是Python编程中常见的操作,下面我将介绍多种实现列表去重的方法,从基础到进阶,帮助初学者全面掌握这一技能。方法一:使用集合(set)去重(最简单)pythondefremove_dupl...

Python枚举类工程实践:常量管理的标准化解决方案

本文通过7个生产案例,系统解析枚举类在工程实践中的应用,覆盖状态管理、配置选项、错误代码等场景,适用于Web服务开发、自动化测试及系统集成领域。一、基础概念与语法演进1.1传统常量与枚举类对比#传...

让Python枚举更强大!教你玩转Enum扩展

为什么你需要关注Enum?在日常开发中,你是否经常遇到这样的代码?ifstatus==1:print("开始处理")elifstatus==2:pri...

Python枚举(Enum)技巧,你值得了解

枚举(Enum)提供了更清晰、结构化的方式来定义常量。通过为枚举添加行为、自动分配值和存储额外数据,可以提升代码的可读性、可维护性,并与数据库结合使用时,使用字符串代替数字能简化调试和查询。Pytho...

78行Python代码帮你复现微信撤回消息!

来源:悟空智能科技本文约700字,建议阅读5分钟。本文基于python的微信开源库itchat,教你如何收集私聊撤回的信息。[导读]Python曾经对我说:"时日不多,赶紧用Python"。于是看...

登录人人都是产品经理即可获得以下权益

文章介绍如何利用Cursor自动开发Playwright网页自动化脚本,实现从选题、写文、生图的全流程自动化,并将其打包成API供工作流调用,提高工作效率。虽然我前面文章介绍了很多AI工作流,但它们...

Python常用小知识-第二弹(python常用方法总结)

一、Python中使用JsonPath提取字典中的值JsonPath是解析Json字符串用的,如果有一个多层嵌套的复杂字典,想要根据key和下标来批量提取value,这是比较困难的,使用jsonpat...

取消回复欢迎 发表评论: