前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV 人脸识别简介

OpenCV 人脸识别简介

作者头像
用户6021899
发布2019-09-29 17:05:08
1.5K0
发布2019-09-29 17:05:08
举报

OpenCV 有三种人脸识别的算法:

  • Eigenfaces 是通过 PCA(主成分分析)实现的,它识别人脸数据集的主成分,并计算出待识别图像区域相对于数据集的发散程度(0~20k),该值越小,表示差别越小,0值表示完全匹配。低于4k~5k都是相当可靠的识别。
  • FisherFaces 是从 PCA发展而来,采用更复杂的计算,容易得到更准确的结果。低于4k~5k都是相当可靠的识别。
  • LBPH 将人脸分成小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。它允许待检测人脸区域可以和数据集中图像的形状、大小不同,更方便灵活。参考值低于50则算是好的识别,高于80则认为比较差。

当然,除了这三种预定义的算法外,我们可以自己写深度学习算法或者其他机器学习的分类算法来进行人脸识别,这里不再详述。

不管使用哪种算法都需要有训练集。从视频或者动图创建训练集的效率比较高。我从网上下载了一些明星的动图,然后分解,检测人脸区域,全部存为200X200的灰度图,存入对应的文件夹中,创建训练集。

代码语言:javascript
复制
from PIL import Image
import os
import cv2
def gifSplit2Array(gif_path):
    import numpy as np
    img = Image.open(gif_path)
    for i in range(img.n_frames):
        img.seek(i)
        new = Image.new("RGBA", img.size)              
        new.paste(img)
        arr = np.array(new).astype(np.uint8)  # image: img (PIL Image):
        yield arr[:,:,2::-1] # 逆序(RGB 转BGR), 舍弃alpha通道, 输出数组供openCV使用
     
def face_generate(img):
   
    gray =cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
   
    front_face_cascade = cv2.CascadeClassifier(r'E:\Python36\MyPythonFiles\my OpenCV\face_detection\cascades/haarcascade_frontalface_default.xml')#检测正脸
    faces0 = front_face_cascade.detectMultiScale(gray, 1.02, 5)
   
    #eye_cascade = cv2.CascadeClassifier('./cascades/haarcascade_eye.xml')#检测眼睛
    eye_cascade = cv2.CascadeClassifier(r'E:\Python36\MyPythonFiles\my OpenCV\face_detection\cascades/haarcascade_eye_tree_eyeglasses.xml')#检测眼睛
    for (x, y, w, h) in faces0:
        face_area = gray[y: y+h, x: x+w] # (疑似)人脸区域
        quasi_eyes = eye_cascade.detectMultiScale(face_area, 1.03, 5, 0)#在人脸区域检测眼睛
        if len(quasi_eyes) ==0: continue
        quasi_eyes = tuple(filter(lambda x : x[2]/w>0.18 and x[1]<0.5*h, quasi_eyes)) # ex,ey,ew,eh; ew/w>0.18 #尺寸过滤 ,且眼睛在脸的上半部
        if len(quasi_eyes) <1 : continue
        yield cv2.resize(face_area, (200,200))
i = 0
for gif_path in ("Yangme5.gif","Yangme6.gif","Shishi.gif","Shishi2.gif","Shishi3.gif","Shishi3.gif" ,"Yangzi.gif","Yangzi2.gif","Yangzi3.gif","Zhenshuang.gif","ZDY.gif", "ZDY2.gif"):
    print(gif_path)
    for img in gifSplit2Array(gif_path):
        for face in face_generate(img):
            cv2.imwrite("./dataset/%s.pgm" % (i), face)
            print(i)
            i += 1

我们可以剔除掉其中一些效果不好的图片。

接着我们加载数据集,训练模型:

代码语言:javascript
复制
def load_dataset(datasetPath):
    names = []
    X = []
    y = []
    ID = 0
    for name in os.listdir(datasetPath):
        subpath = os.path.join(datasetPath, name)
        if os.path.isdir(subpath):
            names.append(name)
            for file in os.listdir(subpath):
                im = cv2.imread(os.path.join(subpath,file), cv2.IMREAD_GRAYSCALE)
                X.append(np.asarray(im, dtype = np.uint8))
                y.append(ID)
            ID += 1
    X = np.asarray(X)
    y = np.asarray(y, dtype = np.int32)
    return X, y, names
 
 datasetPath =".\dataset"    
X, y , names = load_dataset(datasetPath)
#报错找不到face模块是因为只安装了主模块
#pip uninstall opencv-python,   pip install opencv0-contrib-python
#创建人脸识别模型(三种识别模式)
#model = cv2.face.EigenFaceRecognizer_create() #createEigenFaceRecognizer()函数已被舍弃
#model = cv2.face.FisherFaceRecognizer_create()
model = cv2.face.LBPHFaceRecognizer_create() #
model.train(X, y)

最后我们将待预测的图像中的人脸区域与训练集中的图像进行比对预测:

代码语言:javascript
复制
def recognize(img):
    global model, names
    gray =cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    front_face_cascade = cv2.CascadeClassifier(r'E:\Python36\MyPythonFiles\my OpenCV\face_detection\cascades/haarcascade_frontalface_default.xml')#检测正脸
    faces0 = front_face_cascade.detectMultiScale(gray, 1.025, 5)
    eye_cascade = cv2.CascadeClassifier(r'E:\Python36\MyPythonFiles\my OpenCV\face_detection\cascades/haarcascade_eye_tree_eyeglasses.xml')#检测眼睛
    for (x, y, w, h) in faces0:
        #print(x,y,w,h)
        face_area = gray[y: y+h, x: x+w] #疑似人脸区域
        quasi_eyes = eye_cascade.detectMultiScale(face_area, 1.03, 5, 0)#在人脸区域检测眼睛
        if len(quasi_eyes) ==0: continue
        quasi_eyes = tuple(filter(lambda x : x[2]/w>0.15, quasi_eyes)) # ex,ey,ew,eh; ew/w>0.18 #尺寸过滤
        #print(quasi_eyes)
        if len(quasi_eyes) <1 : continue#if len(quasi_eyes) <2 : continue
        cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255), 2) #画红色矩形框标记正脸
        roi = cv2.resize(face_area, (200,200), interpolation = cv2.INTER_LINEAR) #尺寸缩放到与训练集中图片的尺寸一致
        cv2.imwrite("e.pgm", roi) #若识别错误,可以添加到正确的数据集,提高后续的识别率
        ID_predict, confidence = model.predict(roi)#预测!!!
        name = names[ID_predict]
        print("name:%s, confidence:%.2f"%(name, confidence))
        text = name if confidence <70 else "unknow" #10000 for EigenFaces #70 for LBPH
        cv2.putText(img, text , (x, y-20), cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)#绘制绿色文字
    return img
    
imgPath = "AA.jpg"
img = cv2.imread(imgPath)
cv2.imshow(imgPath, recognize(img))
cv2.waitKey()
cv2.destroyAllWindows()

下面是一些预测结果的展示:

单人照:

伪双人照:

三人照(杀马特的诗诗......):

胡歌不在数据集中,所以肯定会识别错误,我们需舍弃置信度过差的结果:

当然,真实的识别效果没这么理想,识别的准确度主要取决于我们的数据集的优劣。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档