用Python进行人脸识别(五)

用python进行人脸识别(五)


OpenCV的基本操作已经学会了,那么开始尝试进行人脸识别吧。

基本原理

人类区分不同的人脸是根据鼻子、醉、眼睛、眉毛、肤色等等因素,这些因素的大小、间距、形状的不同,构成了形形色色的人脸,也构成了这个大千世界。人脸识别的前期就是按照这个思路进行,即几何特征法。但后来发现这玩应儿并不好用,发展出了许许多多的识别方法。

如果人眼是根据鼻子、嘴巴这些组织的“特征”来区别人脸,那计算机可不可以按照其他格式的特征来区别人脸呢?答案是肯定的。基于面部器官的特征提取、基于模板的特征提取、基于代数方法的特征提取、基于弹性匹配法的特征提取等多重方法应用而生,具体的细节就不介绍了。

但是这个世界上有数十亿人,没有足够的特征点根本无法区分如此庞大的人群。利用深度学习(神经网络)可以得到合适的人脸特征值提取方法。深度学习通过百万千万级别的数据训练,可以自动的提取出那些适合计算机理解的和区分的人脸特征。现在有128、256、512、1024个特征的特征表。face_recognition采用的就是128特征表。

所有的人脸识别都基于一个基础,同一个人的人脸在不同的环境下所提取出的特征值大概相等。只要不带墨镜、口罩一类的遮挡物,我们在不同图像中所看到的人脸基本相同(P图过分的不算),计算机由相同的特征提取方法所提取出的特征值基本相等,而所对应在特征空间中的点应该非常接近,不同的人会离的非常远。

假设某两个点的距离小于某一阈值则认为是同一个人,大于这个阈值则认为是不同的人,通过所提取出的特征点就可以判断是否为同一人,这就是人脸识别的基本思想。阈值的具体数值需要通过大量的实验和工程经验来确定,在不同的环境下所对应的阈值是不同的。

face_recognition所采用的特征值提取方法与人的肤色无关。戴口罩或墨镜等掩饰物会使所提取到的特征值偏离真实的人脸,导致无法识别或者识别错误。而在具体的应用环境中,阈值可能会受到图像采集设备、人物所处环境的较大影响,最终影响识别的成功率。

代码

此例为face_recognition官方给的示例,做了一些改动可以实时的检测人脸。

import cv2
import os
import face_recognition
import numpy
from  PIL import Image

#新建文件夹来存储文件
def make_file():
    if os.path.exists('image_data'):
        pass
    else:
        os.makedirs('image_data')

#获取人物的信息
def get_message():
    #打开摄像头
    cap = cv2.VideoCapture(0)
    #获得名字
    name = str(input("please input your name"))
    #创建图片存储路劲
    new_path = 'image_data/' + name + '.jpg'
    #启动LBP模型 识别人脸
    face_cascade = cv2.CascadeClassifier("C://Users/lenovo/Desktop/opencv-files/lbpcascade_frontalface.xml")#打开LBP模型文件  需要提前下载文件 路径自行改动

    while True:
        ret, image = cap.read()

        if ret:#如果成功捕获图像
            cv2.putText(image, 'please look forward', (10, 20), cv2.FONT_HERSHEY_COMPLEX, 1.0, (255, 255, 255), 1)
            gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)  # 转化为灰度图
            faces = face_cascade.detectMultiScale(gray, 1.3, 5)
            for (x, y, w, h) in faces:
                cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)
            if (len(faces) != 0):
                cv2.imwrite(new_path, gray)
                break
            cv2.imshow('test2', image)

        if cv2.waitKey(1) & 0xff == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()
    return new_path, name

def get_image_encond(image_path, image_name):
    image = face_recognition.load_image_file(image_path)

    enconding_name = str(image_name) + '_face_encoding'
    enconding_name = face_recognition.face_encodings(image)[0]

    return enconding_name

人脸识别程序:

import cv2
import dlib
import face_recognition
from image_reserve import get_message, get_image_encond
from add_chinese import change_cv2_draw
import os

#打开摄像头
video_capture = cv2.VideoCapture(0)

#识别已有的图片  需要先下载奥巴马和拜登的图片
obama_image = face_recognition.load_image_file('C://Users/lenovo/Desktop/test-data/test1.jpg')#载入图片
obama_face_enconding = face_recognition.face_encodings(obama_image)[0]#将图片进行编码

biden_image = face_recognition.load_image_file('C://Users/lenovo/Desktop/test-data/test2.jpg')
biden_face_enconding = face_recognition.face_encodings(biden_image)[0]


#存入特征值
know_face_encondings = [
    obama_face_enconding,
    biden_face_enconding,
]

#匹配姓名
know_face_names = [
    'OBAMA',
    'Joe Biden',
]


#将新的人脸编码
new_image_path,new_name = get_message()
new_encon = (get_image_encond(new_image_path,new_name))

know_face_encondings.append(new_encon)
know_face_names.append(new_name)

    
face_locations = []
face_encondings = []
process_this_frame = True

#实时检测
while True:
#读取摄像头图像
ret, frame = video_capture.read()

#把图片变成原来的 1/4  大小  减少计算量  加快运行速率
small_frame =cv2.resize(frame, (0,0), fx=0.25, fy=0.25)

rgb_samll_frame = small_frame[:, :, ::-1]

if process_this_frame:
    #在视频中找出所有的人脸 并将它们编码
    face_locations = face_recognition.face_locations(rgb_samll_frame)
    face_encondings = face_recognition.face_encodings(rgb_samll_frame, face_locations)

    face_names = []

    for face_enconding in face_encondings:

        #跟已有的数据库进行查询
        matches = face_recognition.compare_faces(know_face_encondings, face_enconding, tolerance=0.5)
        name = 'unKnown'

        if True in matches:
            first_match_index = matches.index(True)
            name = know_face_names[first_match_index]

        face_names.append(name)

process_this_frame = not  process_this_frame
for(top, right, bottom, left), name in zip(face_locations, face_names):
    top *= 4
    right *= 4
    bottom *= 4
    left *= 4

    cv2.rectangle(frame, (left, top), (right, bottom), (0,0,255), 2)  #画出边框
    font = cv2.FONT_HERSHEY_DUPLEX
    cv2.putText(frame, name, (left, top), font, 1.0, (255,255,255), 1)
    frame = change_cv2_draw(frame, name, (left, top), 50, (255,0,0)) 

cv2.imshow('video', frame) #显示图像

if cv2.waitKey(1) & 0xff == ord('q'):  #按下q 退出
    break

video_capture.release()#关闭摄像头
cv2.destroyAllWindows()
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值