只用opencv-python进行人脸识别,比face_recognition识别正确率高!完整代码!!!

这篇文章的话题依然是人脸识别,不过仅仅使用了opencv-python以及opencv-contrib-python这两个包,而且就我做的测试用例来看识别的正确率比face_recognition还要更高,话不多说,咱们这就开始。

人脸检测

要想做人脸识别,人脸检测必须是要做的,毕竟识别也得你检测到人脸之后才能辨别。那么如何检测到人脸呢?提取出图像的细节对产生稳定分类结果很重要,这些提取的结果被称为特征,专业的表述为:从图像数据中提取特征。虽然任意像素都可以能影响多个特征,但特征应该比像素少得多。两个图像的相似程度可以通过它们对应特征的欧氏距离来度量。 Haar 特征是一种用于实现实时人脸跟踪的征。每一个 Haar 特征都描述了相邻图像区域的对比模式。例如,边、顶点和细线都能生成具有判别性的特征。获取 Haar 特征的方法有很多种,这里我用的是安装opencv以后opencv安装目录里的部分xml文件获取的,如果你不想安装opencv的话,也可以到文末直接下载我打包好的文件。如果你已经安装了opencv,找到你的安装目录,一般如下图:


接着打开sources/data/haarcascades文件夹,你会看到下图:

我提供的资源就是上图所示的所有xml文件,不用再在电脑上安装opencv了。默认的人脸检测器是haarcascade_frontalface_default.xml。当然这个是可以更改的,使用的方法如下:

face_detector = cv2.CascadeClassifier('D:/OPENCV/sources/data/haarcascades/haarcascade_frontalface_default.xml')

for i in range(len(person_list)):

    person_name = os.listdir("faces/" + "person_" + str(i + 1))

    img_path = "faces/" + "person_" + str(i + 1) + "/" + person_name[0]

    # opencv人脸检测

    PIL_img = Image.open(img_path).convert('L')

    img_numpy = np.array(PIL_img, 'uint8')

    faces = face_detector.detectMultiScale(img_numpy)

    #print(len(faces))

    for x,y,w,h in faces:

        face_sampes.append(img_numpy[y:y+h, x:x+w])

        ids.append(i + 1)

face_sampes,ids是训练数据用到的两个参数,face_sampes是人脸特征矩阵,ids是每个人脸对应的id。

训练数据

这部分比较简单,如果有异常应该是未安装opencv-contrib-python导致的,直接上代码了。

opencv_recognizer = cv2.face.LBPHFaceRecognizer_create()

opencv_recognizer.train(face_sampes, np.array(ids))

opencv_recognizer.write('train/train.yml')

执行完代码之后会在当前目录生成train.yml文件,人脸识别的时候会用到。

人脸识别

相信大家都已经看到了我在训练数据时使用的代码,其中opencv_recognizer是比较重要的,当然其实是cv2.face.LBPHFaceRecognizer_create()比较重要。这个人脸识别主要用的是LBPH算法**。它将检测到的人脸分为小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。由于这种方法的灵活性,LBPH是唯一允许模型样本人脸和检测到的人脸在形状、大小上可以不同的人脸识别算法。具体的用法见以下代码。

opencv_recognizer.read('train/train.yml')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

new_faces = face_detector.detectMultiScale(gray)

for x, y, w, h in new_faces:

        cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2)

        id, confidence = opencv_recognizer.predict(gray[y:y+h, x:x+w])

        cv2.putText(img, face_names[id-1]+str(int(confidence)), (x + 6, y + h - 6), font, 1.0, (255, 255, 255), 1)

识别的主体在predict方法中,它的返回值一个是id,一个是置信度。id是与人脸一一对应的,好的置信度要低于50,越小越好。高于80的置信度都是较差的。然后由于我可以根据id得到人的姓名,所以我可以直接把人名实时显示在摄像头视频中如何做到的欢迎移步这里看我的人脸照片目录结构,谢谢大家。

完整代码附上:

import cv2

import os

import numpy as np

from PIL import Image

face_detector = cv2.CascadeClassifier('D:/OPENCV/sources/data/haarcascades/haarcascade_frontalface_default.xml')

face_sampes = []

ids = []

font = cv2.FONT_HERSHEY_DUPLEX

face_names = []

person_list = os.listdir("faces/")

for i in range(len(person_list)):

    person_name = os.listdir("faces/" + "person_" + str(i + 1))

    img_path = "faces/" + "person_" + str(i + 1) + "/" + person_name[0]

    face_names.append(person_name[0][:person_name[0].index(".")])

    # opencv人脸检测

    PIL_img = Image.open(img_path).convert('L')

    img_numpy = np.array(PIL_img, 'uint8')

    faces = face_detector.detectMultiScale(img_numpy)

    for x,y,w,h in faces:

        face_sampes.append(img_numpy[y:y+h, x:x+w])

        ids.append(i + 1)

opencv_recognizer = cv2.face.LBPHFaceRecognizer_create()

opencv_recognizer.train(face_sampes, np.array(ids))

opencv_recognizer.write('train/train.yml')

camera = cv2.VideoCapture(0)

while True:

    success, img = camera.read()

    opencv_recognizer.read('train/train.yml')

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    new_faces = face_detector.detectMultiScale(gray)

    for x, y, w, h in new_faces:

        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

        id, confidence = opencv_recognizer.predict(gray[y:y + h, x:x + w])

        cv2.putText(img, face_names[id - 1] + str(int(confidence)), (x + 6, y + h - 6), font, 1.0, (255, 255, 255), 1)

    cv2.imshow('camera', img)

    cv2.waitKey(0)

    cv2.destroyAllWindows()


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容