基于opencv-python的人脸识别功能

发布于 2022-03-02  339 次阅读


在简略的过完python知识之后,我想做一些小型的python项目来练练手,在四处寻找之后,发现了这个项目。

其原理就是用python语言以及 开源opencv-python 来实现对人脸的采集以及校准,得到人脸识别的效果,看似十分的

难,实际上在有了opencv的帮助下,这一系列都变的简单儿随意。

1,环境配置

首先是python环境

可以在Python的官方网站(Welcome to Python.org)下载对应的python版本,并进行安装,在安装时可以选择add path 一键自动添加环境变量。

其次是python编译器

我使用的是pycharm编译器,如使用的是visual studio code 需自行百度如何配置 vscode 的环境。

最后需要添加我们的opencv - python 以及 opencv - contrib - python 包

pycharm就只需要 **文件——>设置-——>项目——>项目解释器——>“+”号添加然后进行搜索安装就行**

另外也可以通过cmd 进行 安:

pip install opencv-pyhton
pip install opencv-contrib-python

进行安装。

此外 还可以到opencv官网去进行下载安装(Home - OpenCV

2,开始写代码

①首先,我们要导入包

众所周知,python导入包只需要 import 就行了

②读入一张图片

# 导入 cv 模块
import cv2 as cv

#读取 图片

img = cv.imread('2.jpg')

#显示 图片

cv.imshow('read_img', img)

#显示的时长

cv.waitKey(0)#0会使程序一直展现图片、改成其他数字即可过一会儿自动关闭

#释放内存

cv.destroyAllWindows()

③灰度转换

在读入图片时进行一下操作即可

gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

即可将img 灰度转换后放入gary_img

④绘制矩形

使用cv.rectangle(图片名称, 位置坐标, 颜色,线条宽度)

同样使用cv.circle(图片名称,中心店坐标,半径,颜色,线条宽度)‘

# 坐标
x,y,w,h = 100,100,100,100
#绘制矩形
cv.rectangle(img,(x,y,x+w,y+h),color=(0,0,255), thickness=1)
# 绘制圆形
cv.circle(img, center=(x+w,y+h), radius=100, color=(255, 0, 0), thickness=2)

⑤人脸检测

导入opencv的人脸检测功能

首先,打开opencv的文件找到其中的

haarcascade_frontalface_alt2.xml

将其地址以及名称写入括号内,复制过来记得吧斜杆换成反方向的斜杆。
cv.CascadeClassifier(C:/Users/22616/AppData/Local/Programs/Python/Python39/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')

然后再所检测到的人脸范围内进行画框就行

  gary  =  cv.cvtColor(img,cv.COLOR_RGB2GRAY)

    Face_detec = cv.CascadeClassifier('C:/Users/22616/AppData/Local/Programs/Python/Python39/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')

    Face = Face_detec.detectMultiScale(gary,1.01,5,0,(10,10),(100,100))

    for x,y,w,h in Face:

        cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)

        cv.imshow('result',img)

此时打印出来的图片的人物脸上就会出现框框了

框框大小是可以设置的

到这一步我们就大致完成了对人脸的锁定。

⑥视频检索

接下来我们需要对视屏进行检索

原理就是,将视屏的每一帧存为一张图片然后 在进行如上 的操作

#读取摄像头
cap = cv.VideoCapture(0)
#循环
c = 0
while True:
        flag, frame = cap.read()
        # 降低视频采集帧率为每5帧处理一次,如果不这么做,可能稍微差一点的电脑都会加载不出来。
        if flag:
            if (c % 5 == 0):
                Face_detec_demo(frame)
            c += 1
            cv .waitKey(1)
        else:
            break

⑦人脸录入,数据训练

1),人脸录入,很简单,就是将摄像头捕捉的画面,存为图片即可。

2),数据训练,将所有的图片进行分析,将脸部的特征信息保存在一个文件中,留下记录,在后面人脸识别的时候可以直接调用这个文件,不过最好同一个人多一点照片训练效果更好。

from typing import List
import cv2
import os
import urllib
import urllib.request
from PIL import Image
import numpy as np

def getImageAndLabels(path):
    faceSamples=[]
    ids = []
    imagePaths= [os.path.join(path, f) for f in os.listdir(path)]
    face_detector = cv2.CascadeClassifier('C:/Users/22616/AppData/Local/Programs/Python/Python39/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')

    for imagePath in imagePaths:
        PIL_img = Image.open(imagePath).convert('L')
        img_numpy = np.array(PIL_img,'uint8')
        faces = face_detector.detectMultiScale(img_numpy)
        id = int(os.path.split(imagePath)[1].split('.')[0])
        for x,y,w,h in faces:
            ids.append(id)
            faceSamples.append(img_numpy[y:y+h,x:x+w])

    print('id:',id)
    print('fs:',faceSamples)
    return faceSamples , ids



if __name__ == '__main__':
    path = './downimg/'#图片存储的位置
    faces,ids = getImageAndLabels(path)
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    recognizer.train(faces, np.array(ids))#训练
    recognizer.write('./trainer.yml')#将所有的信息都写入这个xml 文件中
    print('yes')

⑧人脸识别

原理就是调用前面储存的图片人脸特点,与当前人脸进行对比,得到一个信任分数,当分数越大带别越可疑,此时我们就需要发出警告,反之则为安全人物。

总而言之就是将之前的所有点结合起来,利用opencv 就可以实现简单的人脸识别的功能

import cv2
import os
import urllib
import urllib.request

recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('./trainer.yml')
names=[]


def Face_detec_demo(img):
    name()
    gary  =  cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
    Face_detec = cv2.CascadeClassifier('C:/Users/22616/AppData/Local/Programs/Python/Python39/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')
    Face = Face_detec.detectMultiScale(gary,1.01,5,0,(100,100),(300,300))
    for x,y,w,h in Face:
        cv2.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)
        cv2.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=2)

        ids,confidens = recognizer.predict(gary[y:y+h,x:x+w])
        if confidens<80:
            cv2.putText(img,str(names[ids-1]),(x+10,y-10),cv2.FONT_HERSHEY_SIMPLEX,0.75,(0,255,0),2)//把名字打印在头上
        else:
            cv2.putText(img, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)

    cv2.imshow('result',img)

def name():
    path = './downimg/'
    # names = []
    imagePaths = [os.path.join(path , f) for f in os.listdir(path)]
    for imagePath in imagePaths:
        name = str(os.path.split(imagePath)[1].split('.' , 2)[1])
        names.append(name)

#读取摄像头
cap = cv2.VideoCapture(0)
#循环
c = 0
while True:
        flag, frame = cap.read()
        # 降低视频采集帧率为每5帧处理一次
        if flag:
            if (c % 5 == 0):
                Face_detec_demo(frame)
            c += 1
            cv2 .waitKey(1)
        else:
            break


#释放内存

cv2.destroyAllWindows()

至此,一个人脸识别基本上就完成了。

此玩意儿仅能玩玩,还需进行进一步的开发。