人脸识别代码_10行代码实现人脸识别

什么是人脸识别

人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术。用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部识别的一系列相关技术,通常也叫做人像识别、面部识别。

目前的人脸识别技术已经非常成熟了,还发展成3D人脸识别。而且现在各大厂商也都提供了人脸识别的API接口供我们调用,可以说几行代码就可以完成人脸识别。但是人脸识别的根本还是基于图像处理。在Python中最强大的图像处理库就是OpenCV。

OpenCV简介

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

OpenCV基本使用

安装

pip install opencv-python  # 基础库pip install opencv-contrib-python  # 扩展库pip install opencv-python-headless

读取图片

读取和显示图片是最基本的操作了,OpenCV当中使用imread和imshow实现该操作

import cv2 as cv# 读取图片,路径不能含有中文名,否则图片读取不出来image = cv.imread('1111.jpg')# 显示图片cv.imshow('image', image)# 等待键盘输入,单位是毫秒,0表示无限等待cv.waitKey(0)# 因为最终调用的是C++对象,所以使用完要释放内存cv.destroyAllWindows()
f01379cbdbaf9cc5c4c3febe78852694.png

将图片转为灰度图

OpenCV中数百中关于不同色彩控件之间转换的方法。目前最常用的有三种:灰度、BGR、HSV。

  • 灰度色彩空间是通过去除彩色信息来讲图片转换成灰阶,灰度图会大量减少图像处理中的色彩处理,对人脸识别很有效。
  • BGR每个像素都由一个三元数组来表示,分别代码蓝、绿、红三种颜色。python中还有一个库PIL,读取的图片通道是RGB,其实是一样的,只是颜色顺序不一样
  • HSV,H是色调,S是饱和度,V是黑暗的程度
    将图片转换为灰度图
import cv2 as cv# 读取图片,路径不能含有中文名,否则图片读取不出来image = cv.imread('1111.jpg')# cv2读取图片的通道是BGR,# PIL读取图片的通道是RGB# code选择COLOR_BGR2GRAY,就是BGR to GRAYgray_image = cv.cvtColor(image, code=cv.COLOR_BGR2GRAY)# 显示图片cv.imshow('image', gray_image)# 等待键盘输入,单位是毫秒,0表示无限等待cv.waitKey(0)# 因为最终调用的是C++对象,所以使用完要释放内存cv.destroyAllWindows()
7ebd40cfd000dc87a96606d3ca15e86e.png

绘制矩形

image = cv.imread('1111.jpg')x, y, w, h = 50, 50, 80, 80# 绘制矩形cv.rectangle(image, (x, y, x+w, y+h), color=(0, 255, 0), thickness=2)# 绘制圆形cv.circle(image, center=(x + w//2, y + h//2), radius=w//2, color=(0, 0, 255), thickness=2)cv.imshow('image', image)cv.waitKey(0)cv.destroyAllWindows()
3cb46d8721021ea99cd9a9851f7314a2.png

人脸检测

人脸检测实际上是对图像提取特征,Haar特征是一种用于实现实时人脸跟踪的特征。每个Haar特征都描述了相邻图像区域的对比模式。比如边、定点和细线都能生成具有判别性的特征。OpenCV给我们提供了Haar特征数据,在cv2/data目录下,使用特征数据的方法def detectMultiScale(self, image, scaleFactor=None, minNeighbors=None, flags=None, minSize=None, maxSize=None)

  • scaleFactor: 指定每个图像比例缩小多少图像
  • minNeighbors: 指定每个候选矩形必须保留多少个邻居,值越大说明精度要求越高
  • minSize:检测到的最小矩形大小
  • maxSize: 检测到的最大矩形大小

检测图片中人脸

import osimport cv2 as cvdef face_detect_demo(image):    # 将图片转换为灰度图    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)    # 加载特征数据    face_detector = cv.CascadeClassifier(os.path.join(cv.data.haarcascades, 'haarcascade_frontalface_default.xml'))    faces = face_detector.detectMultiScale(gray)    for x, y, w, h in faces:        cv.rectangle(image, (x, y), (x + w, y + h), color=(0, 255, 0), thickness=2)# 读取图片,路径不能含有中文名,否则图片读取不出来image = cv.imread('2222.jpg')face_detect_demo(image)# 显示图片cv.imshow('image', image)# 等待键盘输入,单位是毫秒,0表示无限等待cv.waitKey(0)# 因为最终调用的是C++对象,所以使用完要释放内存cv.destroyAllWindows()
2afe246ad613d6ebce3d195c57035078.png

采用默认参数,检测人脸数据不全,需要调整detectMultiScale函数的参数,调整为faces = face_detector.detectMultiScale(gray, scaleFactor=1.02, minNeighbors=3)

2c9d25f7f24485f44c7ce8a81e7d8889.png


我们发现除了检测到人脸数据,还有一些其他的脏数据,这个时候可以打印检测出的人脸数据位置和大小

faces = face_detector.detectMultiScale(gray, scaleFactor=1.02, minNeighbors=3)for x, y, w, h in faces:    print(x, y, w, h) # 打印每一个检测到的数据位置和大小    cv.rectangle(image, (x, y), (x + w, y + h), color=(0, 255, 0), thickness=2)
b767741ccaf4d34ed01f4388cfa9011e.png

从大小中我们看到最大的两个矩形,刚好是人脸数据,其余都是脏数据,那么继续修改函数参数faces = face_detector.detectMultiScale(gray, scaleFactor=1.02, minNeighbors=3, minSize=(80, 80))

080c6a5a8b258cb4e1bf6aa0a9139c96.png

检测视频中人脸

视频就是一张一张的图片组成的,在视频的帧上面重复这个过程就能完成视频中的人脸检测了。视频读取OpenCV为我们提供了函数VideoCapture,参数可以是视频文件或者0(表示调用摄像头)

import cv2 as cv# 人脸检测def face_detect_demo(image):    try:        # 将图片转换为灰度图        gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)        # 加载特征数据        face_detector = cv.CascadeClassifier(os.path.join(cv.data.haarcascades, 'haarcascade_frontalface_default.xml'))        faces = face_detector.detectMultiScale(gray)        for x, y, w, h in faces:            print(x, y, w, h)            cv.rectangle(image, (x, y), (x + w, y + h), color=(0, 255, 0), thickness=2)    except Exception as e:        passcap = cv.VideoCapture('人脸识别.mp4')while cap.isOpened():    flag, frame = cap.read()    face_detect_demo(frame)    cv.imshow('result', frame)    if ord('q') == cv.waitKey(5):        breakcap.realse()cv.destroyAllWindows()
8fb0f597edf6259fbed32428e06aeeb9.gif

这个我们是做的人脸识别,怎么把爱好都识别了,这么先进吗?很显然这不太符合我们的要求,爱好只能藏在心里,你给我检测出来就不行了。所以我们必须要进行优化处理。OpenCV为我们提供了一个机器学习的小模块,我们可以训练它,让它只识别我们需要的部分,不要乱猜测。

训练数据

训练数据就是我们把一些图片交给训练模型,让模型熟悉她,这样它就能更加准确的识别相同的图片。训练的数据一般我们可以从网上搜索:人脸识别数据库,或者从视频中保存美帧的数据作为训练集。所有的人脸识别算法在他们的train()函数中都有两个参数:图像数组和标签数组。这些标签标示进行识别时候的人脸ID,根据ID可以知道被识别的人是谁。

获取训练集

从视频中每隔5帧截取一个图片,保存成图片

import cv2cap = cv2.VideoCapture('人脸识别.mp4')number = 100count = 1while cap.isOpened() and number > 0:    flag, frame = cap.read()    if not flag:        break    if count % 5 == 0:        # 按照视频图像中人脸的大体位置进行裁剪,只取人脸部分        img = frame[70:280, 520:730]        cv2.imwrite('data/{}.png'.format(number), img)        number -= 1    count += 1cap.release()cv2.destroyAllWindows()
8c53389a39daa3e6ddfcbfddb570c7c1.png

使用LBPH训练模型

def getImageAndLabels(path_list):    faces = []    ids = []    image_paths = [os.path.join(path_list, f) for f in os.listdir(path_list) if f.endswith('.png')]    face_detector = cv.CascadeClassifier(os.path.join(cv.data.haarcascades, 'haarcascade_frontalface_default.xml'))    for image in image_paths:        img = cv.imread(image)        gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)        faces = face_detector.detectMultiScale(gray)        _id = int(os.path.split(image)[1].split('.')[0])        for x, y, w, h in faces:            faces.append(gray[y:y+h, x:x+w])            ids.append(_id)    return faces, idsfaces, ids = getImageAndLabels('data')# 训练recognizer = cv.face.LBPHFaceRecognizer_create()recognizer.train(faces, np.array(ids))# 保存训练特征recognizer.write('trains/trains.yml')

基于LBPH的人脸识别

LBPH将检测到的人脸分为小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。调整后的区域中调用predict函数,该函数返回两个元素的数组,第一个元素是所识别的个体标签,第二个元素是置信度评分。所有的算法都有一个置信度评分阈值,置信度评分用来衡量图像与模型中的差距,0表示完全匹配。LBPH有一个好的识别参考值要低于50。基本步骤为:

  • cv.VideoCapture读取视频
  • Haar算法检测人脸数据
  • 基于LBPH训练集得到准确人脸数据,并输出标记此人是谁
  • 按置信度取准确度高的人脸标记出来
import osimport cv2 as cvdef face_detect_demo(image):    try:        global number        # 将图片转换为灰度图        gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)        # 加载特征数据        faces = face_detector.detectMultiScale(gray, scaleFactor=1.02, minNeighbors=3)        for x, y, w, h in faces:            # 获取置信度,大于80表示取值错误            _id, confidence = recognizer.predict(gray[y:y + h, x:x + w])            if confidence < 80:                cv.rectangle(image, (x, y), (x + w, y + h), color=(0, 255, 0), thickness=2)    except Exception as e:        passdef check_face():    cap = cv.VideoCapture('人脸识别.mp4')    while cap.isOpened():        flag, frame = cap.read()        if not flag:            break        face_detect_demo(frame)        cv.imshow('img', frame)        cv.waitKey(2)    cv.destroyAllWindows()if __name__ == '__main__':    # 加载训练数据文件    recognizer = cv.face.LBPHFaceRecognizer_create()    recognizer.read('trains/trains.yml')    face_detector = cv.CascadeClassifier(os.path.join(cv.data.haarcascades, 'haarcascade_frontalface_default.xml'))    check_face()
217ac680d4990b266770a0bd911ad0e2.gif

总结

通过上面一步步的学习,你是不是对OpenCV人脸识别有个基本的认识了呢?但是我们也看到了,整个人脸识别的主要算法还是基于Haar,而且准确度并不是特别高,主要是会检测出很多非人脸的数据。LBPH是让我们给某个人脸进行标记,告诉我们他是谁,并没有提高实际的检测准确度。现在机器学习是非常火爆的,基于OpenCV的机器学习人脸识别也精确度也很高,下次我们在来对比几种机器学习人脸识别的库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ticketvalidationexception票根不符合目标服务_如何在有效降低企业仓储成本的同时不降低企业的总体服务质量目标水平?...

对于企业而言&#xff0c;如何降低仓储成本&#xff0c;同时要保证物流总成本最低和不降低企业的总体服务质量和目标水平的前提下进行&#xff0c;常见的措施有以下几点&#xff1a;一用“先进先出方式&#xff0c;减少仓储物的保管风险。”先进先出是储存管理的准则之一&#…

python科学计算_可视化图解Python科学计算包NumPy

NumPy包是python生态系统中数据分析、机器学习和科学计算的主力。 它极大地简化了向量和矩阵的操作。Python的一些主要软件包依赖于NumPy作为其基础架构的基础部分&#xff08;例如scikit-learn、SciPy、pandas和tensorflow&#xff09;。我们将介绍一些使用NumPy的主要方法&am…

php 导出excel 特殊字符,PHPEXCEL导出,存在特殊字符遇到的问题

[13] > Array([payment_success_at] >[user_name] > ?.琳琳?[remarks] >[product_name] > 香菇[sku_name] > 斤[product_property] > 斤[price_original] > 5.50[price_current] > 5.50[consignee] > ?.琳琳?)以上代码中用户名中存在特殊符号…

win10任务栏怎么还原到下面_详解:新版 WIN 10 V2004 任务栏和开始菜单全透明

是不是很酷炫&#xff1f;继续往下看&#xff0c;你也可以简单做到导语本文将告诉你如何借助一个小工具&#xff0c;将最新版 WIN 10 开始菜单和任务栏设置成全透明&#xff0c;以获得超酷的视觉体验。安装和设置都很简单&#xff0c;关键是一定要找到适合 WIN 10 版本的 Start…

10.8.8.8柠檬wifi网页登录_基于企业邮箱进行wifi实名认证的方案

之前我们介绍过如何用钉钉认证和企业微信认证来实现企业内部的实名上网认证。此外邮箱认证也是企业进行wifi实名认证的一个有效手段。因为很多企业都给员工开通了企业邮箱&#xff0c;直接让员工输入邮箱账号和密码进行认证上网。配置、使用和维护都相对比较简单。本文我将介绍…

php tire树,Immutable.js源码之List 类型的详细解析(附示例)

本篇文章给大家带来的内容是关于Immutable.js源码之List 类型的详细解析(附示例)&#xff0c;有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对你有所帮助。一、存储图解我以下面这段代码为例子&#xff0c;画出这个List的存储结构&#xff1a;let myL…

nodejs missing script: dev_nodejs深入学习系列之v8基础篇

V8这个概念大家都不陌生了&#xff0c;那么你动手编译过V8源码吗&#xff1f;编译后有尝试去了解V8背后的一些概念吗&#xff1f;如果没有&#xff0c;那么也不用心慌&#xff0c;下文将跟大家一一解释这些东西。在编译V8之前我们先要了解一个东西-构建系统1、构建系统1.1、构建…

cmos存储器中存放了_天津大学姚建铨院士,张雅婷副教授JMCC:具有宽光谱调控特性的阻变存储器...

【引言】存储器是计算机中数据存放的主要介质。随着5G时代到来&#xff0c;带动人工智能、物联网、智慧城市等应用市场发展并向存储器提出多样化需求&#xff0c;加上传统存储器市场价格变化等因素&#xff0c;新型存储器将在市场发挥越来越重要的作用。因此具有存储密度更高&a…

matlab转差频率控制,转差频率控制的异步电机调速系统的研究

1 引言交流变频调速的方法是异步电机最有发展前途的调速方法。随着电力电子技术、计算机技术和自动控制技术的不断发展&#xff0c;交流电机变频调速已经逐步取代直流电机调速&#xff0c;并经历了采用电压频率协调控制、转差频率控制、矢量控制以及直接转矩控制的发展过程。其…

oracle错误1327,Oracle中的PGA监控报警分析(r11笔记第97天)

最近接到一个数据库报警&#xff0c;让我颇有些意外&#xff0c;这是一个PGA相关的报警。听起来感觉是应用端的资源调用出了问题。报警内容大体如下&#xff1a;报警内容: PGA Alarm on alltest------------------------------------报警级别: PROBLEM------------------------…

php函数内的循环,PHP 循环列出目录内容的函数代码

PHP 循环列出目录内容的函数代码复制代码 代码如下:function list_files($dir){if(is_dir($dir)){if($handle opendir($dir)){while(($file readdir($handle)) ! false){if($file ! "." && $file ! ".." && $file ! "Thumbs.db&quo…

python火柴人打架代码_python火柴人

广告关闭 腾讯云11.11云上盛惠 &#xff0c;精选热门产品助力上云&#xff0c;云服务器首年88元起&#xff0c;买的越多返的越多&#xff0c;最高返5000元&#xff01; 代码实现了一个火柴人&#xff0c;他开心时可以跳跃、可以舞蹈&#xff0c;不开心时可以躺地上... ?代码有…

spring boot admin 2.2 获取日志失败_SB实战20-Spring Boot的日志和报告

上篇我们学习了《SB实战19-Spring Boot的外部配置》&#xff0c;本篇我们学习Spring Boot的日志和报告。4 日志和报告4.1 日志日志是对应用运行时进行调试和分析的重要工具。Spring Boot使用SLF4J作为日志的API&#xff0c;Logback、Log4j2、Java Util Logging都可以作为日志提…

sqlserver date类型和字符串比较_基于SQL Server数据库搭建主从复制实现读写分离实战演练...

一、课程介绍读写分离(主从同步)从字面意思就可以理解&#xff0c;就是把对数据库的读操作和写操作分离开。读写分离在网站发展初期可以一定程度上缓解读写并发时产生锁的问题&#xff0c;将读写压力分担到多台服务器上。读写分离的基本原理是让主数据库处理事务性增、改、删操…

linux非标准头文件,Linux学习:unix的标准化的实现(Linux中各种限制-数据类型-各种标准化头文件介绍)...

作为Linux的前身&#xff0c;unix标准化是十分重要的。我在这里挑几个重要的点说明。1&#xff1a;Linux中各种限制。Linux中限制有编译时限制和运行时限制&#xff0c;另外有一些限制是由于我们的实现不同而不同&#xff0c;因此我们需要调用对应的函数获取对应的值不同。(eg&…

51单片机怎么显示当前时间_(进阶篇)51单片机之按键控制蜂鸣器、数码管、按键值移位显示...

一、实操演示- 按键控制蜂鸣器1、图文详细独立按键硬件电路蜂鸣器硬件电路2、连接方式&#xff1a;J20的第3号引脚连接到J7引脚&#xff0c;即P15连接J7。J29的第7、8号引脚连接到JP1的第1、2号引脚&#xff0c;即P31连接k1&#xff0c;P30连接k2。下载程序后&#xff0c;观察现…

linux怎么运行g77,Linux安装g77编译器的技巧

在Ubuntu10.10系统中&#xff0c;g77已经被gfortran完全替代了&#xff0c;但并不能完全兼容过去的g77&#xff0c;这样就不能使用一些用977编译的程序了。所以我们只能自己再安装g77了。今天华军小编给大家展示的是Linux安装g77编译器的技巧&#xff0c;精心挑选的内容希望大家…

vs使用未初始化的内存怎么解决_遇到C语言内存错误怎么办?一定要找准这六个原因...

一、没有为指针分配内存定义了指针变量&#xff0c;但是没有为指针分配内存&#xff0c;即指针没有指向一块合法的内存。浅显的例子就不举了&#xff0c;这里举几个比较隐蔽的例子。1、结构体成员指针未初始化struct student { char *name; int score; }stu,*pstu; int main() …

cad求和插件_黑科技 | 无BIM建模下平面CAD自动生成门窗表

如果你接到的施工图既不是用天正出的&#xff0c;也不是用revit出的&#xff0c;还得统计门窗表&#xff0c;那么你需要读完这篇文章。为了能够让自己和所有底层同行们从这项无脑又烧脑的机械劳动中解脱&#xff0c;C君近期利用茶余饭后的时间开发了一个小插件&#xff0c;可以…

linux数据库实例开机启动,linux下数据库实例开机自启动设置

linux下数据库实例开机自启动设置 1、修改/oratab [rootorg54 ~]# vi/etc/oratab --把N改为Y&#xff0c;如下提示 # This file is used by ORACLEutilities. It is created by root.sh # and updated by the Database ConfigurationAssistant when creating # a datablinux下数…