简单的opencv人脸识别

11 篇文章 0 订阅

opencv人脸识别

opencv人脸识别器:

  1. EigenFaces(本征)人脸识别器识别器- cv2.face.createEigenFaceRecognizer()–只关注面部的独特特征

    • 它从该新图像中提取主要成分,并将该成分与其在训练过程中存储的成分列表进行比较,找到最匹配的成分,并返回与该最匹配成分关联的人员标签。
  2. FisherFaces人脸识别器识别器- cv2.face.createFisherFaceRecognizer()–前一种的改进

    • Fisherfaces算法不是提取代表所有人的所有面孔的有用特征,而是提取将一个人与其他人区分开的有用特征。
    • 即使在Fisherfaces算法中,如果多个人的图像由于外部光源(如光)而发生急剧变化,它们也将主导其他特征并影响识别精度。
  3. 本地二进制模式直方图(LBPH)人脸识别器- cv2.face.createLBPHFaceRecognizer()–克服光照对前两种的影响

    • LBPH算法尝试找到图像的局部结构,并通过将每个像素与其相邻像素进行比较来做到这一点。
    • 取一个3x3的窗口并将其移动一个图像,每次移动(图像的每个局部),将中心的像素与其相邻像素进行比较。强度值小于或等于中心像素的邻居用1表示,其他用0表示。然后在3x3窗口下按顺时针顺序读取这些0/1值,您将得到一个像11100011这样的二进制模式,该模式是局部的到图像的某些区域。您在整个图像上执行此操作,并且将具有本地二进制模式的列表。

在这里插入图片描述

  • 当您将新图像提供给识别器进行识别时,它将为该新图像生成一个直方图,将该直方图与已有的直方图进行比较,找到最匹配的直方图,并返回与该最佳图像相关联的人员标签匹配直方图。

使用opencv进行人脸识别

步骤:

  1. 准备训练数据:我们将读取每个人/对象的训练图像及其标签,从每个图像中检测面部。
  2. 训练人脸识别器:向OpenCV的LBPH人脸识别器提供我们在步骤1中准备的数据,以对其进行训练。
  3. 测试
import cv2
import os
import numpy as np
import matplotlib.pyplot as plt
%matplotlibinline

训练数据文件夹目录

training-data
 |-------------- s1 
 |                              |-- 1.jpg 
 |                              |-- ... 
 |                              |-- 12.jpg 
 |-------------- s2
 |                              |-- 1.jpg
 |                              |-- ...
 |                              |-- 12.jpg

OpenCV人脸识别器接受标签为整数,因此我们需要定义整数标签和人员实际姓名之间的映射,因此下面我定义人员整数标签及其相应名称的映射。

#训练的数据没有标签0,所以为空

subjects = ["", "Tom Cruise", "Shahrukh Khan"]
#function to detect face using OpenCV
#截取出人脸
def detect_face(img):
    #convert the test image to gray image as opencv face detector expects gray images
    #转为灰度图像
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    #load OpenCV face detector, I am using LBP which is fast
    #there is also a more accurate but slow Haar classifier
    #加载LBP人脸检测器
    face_cascade = cv2.CascadeClassifier('opencv-files/lbpcascade_frontalface.xml')

    #let's detect multiscale (some images may be closer to camera than others) images
    #result is a list of faces
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5);
    
    #if no faces are detected then return original img
    if (len(faces) == 0):
        return None, None
    
    #under the assumption that there will be only one face,
    #extract the face area
    (x, y, w, h) = faces[0]
    
    #return only the face part of the image
    return gray[y:y+w, x:x+h], faces[0]

#此函数将读取所有人的训练图像,从每个图像中检测面部
#并返回两张大小完全相同的列表,一张列表
#张面孔,以及每张面孔的另一张标签列表
def prepare_training_data(data_folder_path):
    
    #------STEP-1--------
    #get the directories (one directory for each subject) in data folder
    dirs = os.listdir(data_folder_path)
    
    #list to hold all subject faces
    faces = []
    #list to hold labels for all subjects
    labels = []
    
    #let's go through each directory and read images within it
    for dir_name in dirs:
        
        #our subject directories start with letter 's' so
        #ignore any non-relevant directories if any
        if not dir_name.startswith("s"):
            continue;
            
        #------STEP-2--------
        #extract label number of subject from dir_name
        #format of dir name = slabel
        #, so removing letter 's' from dir_name will give us label
        label = int(dir_name.replace("s", ""))
        
        #build path of directory containin images for current subject subject
        #sample subject_dir_path = "training-data/s1"
        subject_dir_path = data_folder_path + "/" + dir_name
        
        #get the images names that are inside the given subject directory
        subject_images_names = os.listdir(subject_dir_path)
        
        #------STEP-3--------
        #go through each image name, read image, 
        #detect face and add face to list of faces
        for image_name in subject_images_names:
            
            #ignore system files like .DS_Store
            if image_name.startswith("."):
                continue;
            
            #build image path
            #sample image path = training-data/s1/1.pgm
            image_path = subject_dir_path + "/" + image_name

            #read image
            image = cv2.imread(image_path)
            
            #display an image window to show the image 
            cv2.imshow("Training on image...", image)
            cv2.waitKey(100)
            
            #detect face
            face, rect = detect_face(image)
            
            #------STEP-4--------
            #for the purpose of this tutorial
            #we will ignore faces that are not detected
            if face is not None:
                #add face to list of faces
                faces.append(face)
                #add label for this face
                labels.append(label)
            
    cv2.destroyAllWindows()
    cv2.waitKey(1)
    cv2.destroyAllWindows()
    
    return faces, labels

print("Preparing data...")
faces, labels = prepare_training_data("training-data")
print("Data prepared")

#print total faces and labels
print("Total faces: ", len(faces))
print("Total labels: ", len(labels))

开始训练(使用LBPH)

face_recognizer = cv2.face.createLBPHFaceRecognizer()
face_recognizer.train(faces, np.array(labels))

预测

def draw_rectangle(img, rect):
    (x, y, w, h) = rect
    cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
    
#function to draw text on give image starting from
#passed (x, y) coordinates. 
#cv2.putText(img, text, startPoint, font, fontSize, rgbColor, lineWidth)
def draw_text(img, text, x, y):
    cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0), 2)

def predict(test_img):
    #make a copy of the image as we don't want to chang original image
    img = test_img.copy()
    #detect face from the image
    face, rect = detect_face(img)

    #predict the image using our face recognizer 
    label= face_recognizer.predict(face)
    #get name of respective label returned by face recognizer
    label_text = subjects[label]
    
    #draw a rectangle around face detected
    draw_rectangle(img, rect)
    #draw name of predicted person
    draw_text(img, label_text, rect[0], rect[1]-5)
    
    return img


print("Predicting images...")

#load test images
test_img1 = cv2.imread("test-data/test1.jpg")
test_img2 = cv2.imread("test-data/test2.jpg")

#perform a prediction
predicted_img1 = predict(test_img1)
predicted_img2 = predict(test_img2)
print("Prediction complete")

#create a figure of 2 plots (one for each test image)
f, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

#display test image1 result
ax1.imshow(cv2.cvtColor(predicted_img1, cv2.COLOR_BGR2RGB))

#display test image2 result
ax2.imshow(cv2.cvtColor(predicted_img2, cv2.COLOR_BGR2RGB))

#display both images
cv2.imshow("Tom cruise test", predicted_img1)
cv2.imshow("Shahrukh Khan test", predicted_img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)
cv2.destroyAllWindows()

人脸识别是一个有趣的想法,OpenCV使我们对其进行编码变得极其简单和容易。一个完整的人脸识别应用程序只需要几行代码,我们只需更改一行代码就可以在所有三个人脸识别器之间进行切换。就这么简单。
尽管EigenFaces,FisherFaces和LBPH面部识别器都不错,但是还有更好的方法来进行面部识别,例如使用定向梯度直方图(HOG)和神经网络。因此,如今已经结合使用OpenCV和机器学习来实现更高级的面部识别算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值