人脸识别opencv+python

一、什么是人脸识别

人脸识别(face recognizaton)分为四个部分
人脸检测(face detection):在一张图片中找到人脸所处的位置
人脸对齐(face alignment):在已检测到人脸后,自动找到人脸的眼睛鼻子嘴和脸轮廓等标志性特征位置
人脸校验(face verification):判断两张脸是不是同一个人
人脸识别(face identification):给定一张脸,判断这张脸是谁

二、openCV

全称:Open Source Computer Vision Library,一个跨平台的计算机视觉库,可以用于开发实时的图像处理、计算机视觉以及模式识别程序

1.安装openCV

1.pycharm–terminal
2.执行pip install opencv-python命令

2.使用openCV

①.加载图片
# 导入cv2模块
import cv2 as cv
# 读取图片
img=cv.imread('xiaozhan.png')  # 图片路径不能有中文
# 显示图片(一闪而过)
cv.imshow('read_img',img)      # 第一个参数是图像的帧名称,第二个参数是要显示的图片
# 等待键盘输入才消失
cv.waitKey(0)                  # 为了保证图片一直显示在窗口上,单位是ms,0ms,无限等待,如果传入1000,就是等待1s
# 释放内存空间
cv.destroyAllWindows()         # 由于openCV的底层是C++编写的
②.图片灰度转换

openCV有数百种在不同色彩空间之间的转换方法。
计算机视觉中三种常用的色彩空间:灰度、BGR和HSV

1.灰度色彩空间是通过去除彩色信息来将其转换成灰阶,灰度色彩空间对中间处理特别有效,比如人脸识别。
2.BGR即蓝绿红色彩空间,每个像素点都由一个三原数组来表示,取值0-255。区别RGB色彩空间顺序不同。
3.HSV,H(Hue)是色调,S(Saturation)是饱和度,V(Value)表示黑暗程度(或光谱另一端的明亮程度)。

灰度转换的作用:转换成灰度图片的计算强度得以降低(原来是三色通道直接转换成灰度图片)

# 导入cv2模块
import cv2 as cv
# 读取图片
img=cv.imread('xiaozhan.png')                  # 图片路径不能有中文
# 彩色图片灰度转换                              # cv2读取图片的通道是BGR(蓝绿红),PIL读取图片的通道是RGB
gray_img=cv.cvtColor(img,cv.COLOR_BGR2GRAY)    # COLOR_BGR(彩图)2(TO)GRAY(灰图)
# 显示灰度图片
cv.imshow('gray_img',gray_img)
# 保存灰度图片
cv.imwrite('gray_img.png',gray_img)            # 会被保存在当前路径下
# 等待键盘输入
cv.waitKey(0)                                  # 0ms,无限等待,如果传入1000,就是等待1s
# 释放内存
cv.destroyAllWindows()                         # 由于openCV的底层是C++编写的
③.修改图片的尺寸
# 修改图片的尺寸
import cv2 as cv
img=cv.imread('xiaozhan.png')
# 打印修改前图片的形状(尺寸)
print(img.shape)
# 修改图片的尺寸
resize_img=cv.resize(img,dsize=(250,360))    # dsize=(宽度,高度)
# 打印修改后图片的形状(尺寸)
print(resize_img.shape)
cv.imshow('resize_img',resize_img)
# 等待键盘输入字母q后释放内存
while True:
    if ord('q')==cv.waitKey(0):              # cv.waitKey(0)就是输入键的ASCII码值
        break
cv.destroyAllWindows()
④.画图

确定脸部位置

# 画图
import cv2 as cv
img=cv.imread('xiaozhan.png')
# 画矩形
x,y,w,h=128,135,15,40                                          # w是宽度,h是高度
cv.rectangle(img,(x,y,y+w,y+h),color=(0,255,0),thickness=2)    # x,y,y+w,y+h,分别是矩形的左上角点坐标和右下角点坐标,#color=BGR通道;thickness是宽度
# 画圆形
x2,y2,w2,h2=135,120,130,220
cv.circle(img,center=(x2+w2//2,y2+h2//2),radius=w2//2,color=(0,0,255),thickness=2)   # center为原点坐标,radius为半径
cv.imshow('result image',img)
cv.waitKey(0)
cv.destroyAllWindows()
⑤.人脸检测
Haar级联

概念:从图像数据中提取特征。在产生图像稳定分类和跟踪结果中,提取图像的细节。
---------------------------------------------------------------------------------------------------------------------------------------------
任意像素都可影响多个特征,但特征比像素少的多,两个图像相似度可通过它们对应特征的欧氏距离来度量。
---------------------------------------------------------------------------------------------------------------------------------------------
Haar特征是一种用于实现实时人脸跟踪的特征,每一个Haar特征都描述了相邻图像区域的对比模式。例如,边、顶点和细线都能生成具有判别性的特征。

获取Haar级联数据

下载安装配置opencv

bulid目录是openCV使用时要用到的一些库文件
sources目录是openCV官方提供的一些demo示例源码
sources\data\haarcascades目录存放的是所有openCV人脸检测的xml文件,可以用检测静止图像、视频个摄像头所得到的图像中的人脸。
请添加图片描述

静态图形中单人的人脸检测
import cv2 as cv
import numpy as np                      # Python的开源的数值计算扩展,可用来存储和处理大型矩阵
from matplotlib import pyplot as plt    # matplotlib是Python的绘图库
                                        # pyplot是matplotlib的子库,是常用的绘图模块,能很方便让用户绘制 2D 图表
# 人脸检测函数
def face_detect_demo():                          # detect是侦察的意思
    # 灰度转换
    gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY)      # 以降低色彩通道
    # 加载检测人脸的xml文件
    face_detector = cv.CascadeClassifier('E:\\python\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml')
    # 使用xml文件对获得的灰度图片进行人脸检测
    faces=face_detector.detectMultiScale(gray)    # 第一个参数是要检测的对象,获得的结果是人脸的区域faces
    # 在人脸区域绘制一个矩形
    for x,y,w,h in faces:
        cv.rectangle(src,(x,y),(x+w,y+h),color=(0,255,0),thickness=2)
    cv.imshow('result',src)
# 加载图片
src=cv.imread('xiaozhan.png')
# 调用人脸检测函数
face_detect_demo()
cv.waitKey(0)
cv.destroyAllWindows()
静态图形中多人的人脸检测
import cv2 as cv

def face_detect_demo():
    # 图片灰度转换
    gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    # 加载特征数据
    face_detector = cv.CascadeClassifier('E:\\python\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml')
    # 进行人脸检测并调整精准度
    faces=face_detector.detectMultiScale(gray,scaleFactor=1.03,minNeighbors=3,maxSize=(125,125),minSize=(100,100))   # 使用参数来调整选中的部分,scaleFactor是缩放比例,minNeighbors是最少检测几次,maxSize是选出的最大尺寸,minSize是选出的最小尺寸
    #将人脸用矩形框出
    for x,y,w,h in faces:
        print(x,y,w,h)
        cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)
        cv.circle(img,center=(x+w//2,y+h//2),radius=(w//2),color=(255,0,0),thickness=2)
    # 显示图片
    cv.imshow('result',img)

# 加载图片
img=cv.imread('xiaozhan_wangyibo.jpg')
# 调用人脸检测方法
face_detect_demo()
cv.waitKey(0)
cv.destroyAllWindows()
视频中的人脸检测

视频的每一帧都是一张一张的图片组成的,在视频的帧上重复静态图片检测的过程就可以完成视频的人脸检测

import cv2 as cv
import numpy as np                      # Python的开源的数值计算扩展,可用来存储和处理大型矩阵
from matplotlib import pyplot as plt    # matplotlib是Python的绘图库
                                        # pyplot是matplotlib的子库,是常用的绘图模块,能很方便让用户绘制 2D 图表

def face_detect_demo(img):
    # 图片灰度转换
    gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    # 加载特征数据
    face_detector = cv.CascadeClassifier('E:\\python\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml')
    # 进行人脸检测并调整精准度
    faces=face_detector.detectMultiScale(gray)   # 使用参数来调整选中的部分,scaleFactor是缩放比例,minNeighbors是最少检测几次,maxSize是选出的最大尺寸,minSize是选出的最小尺寸
    #将人脸用矩形框出
    for x,y,w,h in faces:
        print(x,y,w,h)
        cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)
    # 显示图片
    cv.imshow('result', img)

# 加载视频
video=cv.VideoCapture('me.mp4')       # video=cv.VideoCapture()为调用自己的摄像头
# 一直循环,知道没有检测到图片或按q退出
while True:
    # 读取视频中每一帧图片
    flag,frame=video.read()    # 参数flag为True或False,代表有没有读取到图片  第二个参数frame表示截取到一帧的图片
    # 未检测到图片跳出循环
    if not flag:
        break
    # 调用人脸检测方法
    face_detect_demo(frame)
    # 按q退出
    if ord('q')==cv.waitKey(0):
        break
# 释放cv内存空间
cv.destroyAllWindows()
# 释放视频内存空间
video.release()
⑥.人脸识别

概念:一个程序能识别给定图像或视频中的人脸
过程:用一系列分好类的图像来训练程序(录入面部或指纹),并基于这些图像老进行识别
重要特征:每个识别都具有转置信评分,因此可在实际应用中通过对其设置阈值来进行筛选。
人脸获得的方式:1.自己获得图像。2.从人脸数据库免费获取可用的人脸图像
训练数据:将数据加载到人脸识别算法中

pip install opencv-contrib-python 安装opencv-contrib-python模块

图像数组就是那个图像,标签数组就是对应图像的ID,根据ID你就知道他是谁

数据训练
import cv2 as cv
import os
import numpy as np
import sys
from PIL import Image     # pip install pillow 安装PIL模块

def getImagesAndLabels(path):
    # os.path.join(path,f)   将多个路径组合后返回
    # os.listdir(path) 该路径下所有文件和文件夹
    # 将图片路径拼接成一个列表
    imagePaths=[os.path.join(path,f) for f in os.listdir(path)]    # ['./data/jm3/1.png', './data/jm3/10.png', './data/jm3/2.png', './data/jm3/3.jpg', './data/jm3/4.jpg', './data/jm3/5.jpg', './data/jm3/6.png', './data/jm3/7.png', './data/jm3/8.png', './data/jm3/9.png']
    # 图像数组(人脸)的列表
    faceSamples=[]
    # 标签数组(ID)的列表
    ids=[]
    for imagePath in imagePaths:
        # 以L模式打开图片
        # PIL有九种不同模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F
        # L为灰度图像,1为二值图像(非黑即白)
        PIL_img=Image.open(imagePath).convert('L')
        # 将整张灰度图像转换为8位无符号整型的数组矩阵
        img_numpy=np.array(PIL_img,'uint8')
        # 获取每个图片的id,int是将字符串类型转换为int类型
        id=int(os.path.split(imagePath)[1].split(".")[0])      # os.path.split(imagePath)获取的是下面的字典('./data/jm3', '10.png'),前半部分是路径,后半部分是图片名称,后面加一个[1]是获取第二个元素10.png,然后再以.分隔开,取第一个元素10,就是id
        # 加载特征数据
		detector = cv.CascadeClassifier('E:\\python\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml')
        # 获取人脸的部分
        faces=detector.detectMultiScale(img_numpy)
        for (x,y,w,h) in faces:
            # 将整张图片的人脸部分提取出来并放到人脸的列表中
            faceSamples.append(img_numpy[y:y+h,x:x+w])
            # 把id也放进去
            ids.append(id)
        # 返回图片和ID数组
        return faceSamples,ids


if __name__=='__main__':
    # 指定路径
    path='./data/jm3/'
    # 遍历路径,获取到图像数组和标签数组(ID)
    faces,ids=getImagesAndLabels(path)
    # 创建一个LBPH人脸识别模型(获取训练对象)
    recognizer = cv.face.LBPHFaceRecognizer_create()
    # 调用train方法来训练数据,将ids从列表转换为数组
    recognizer.train(faces,np.array(ids))
    #把训练数据保存到文件夹中
    recognizer.write('trainer/trainer.yml')   # yml后缀的文件是用来表达资料序列的编程语言
基于LBPH的人脸识别

LBPH(Local Binary Pattern Histogram)
将检测到的人脸分为小单元,并将其余模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。
LBPH是唯一允许模型样本人脸和检测到的人脸形状、大小上可以不同的人脸识别算法。很灵活

import cv2 as cv
import numpy as np
import os

# 创建训练对象
recognizer=cv.face.LBPHFaceRecognizer_create()
# 加载训练数据集文件
recognizer.read('trainer/trainer.yml')

src=cv.imread('./data/jm3/10.png')
# 对图片进行灰度转换,以降低色彩通道
gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY)
# 加载opencv中检测人脸的xml文件
face_detector = cv.CascadeClassifier('E:\\python\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml')
# 使用xml文件对获得的灰度图片进行人脸检测
faces=face_detector.detectMultiScale(gray)   # 第一个参数是要检测的对象,获得的结果是人脸的区域
# 对检测出的人脸区域绘制一个矩形,要使用src这个全局变量
for x,y,w,h in faces:
    cv.rectangle(src,(x,y),(x+w,y+h),color=(0,255,0),thickness=2)
    # 人脸识别
    id,confidence=recognizer.predict(gray[y:y+h,x:x+w])
    print('标签id',id,'置信评分',confidence)
cv.imshow('result',src)
cv.waitKey(0)
cv.destroyAllWindows()
  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值