人脸识别概述

本文涉及的产品
视觉智能开放平台,分割抠图1万点
视觉智能开放平台,图像资源包5000点
视觉智能开放平台,视频资源包5000点
简介: 人脸识别概述

其实人脸识别在前面我们已经介绍过了,不过那个时候介绍的人脸识别是基于opencv的识别,使用的是已经训练好的数据集。所以,对于人脸识别这个章节的学习,其实已经不需要太多的说明,主要是讲解一下基于深度学习的人脸识别。


人脸识别的主要方法


1.基于几何特征的方法


几何特征的检测方法最早是由Kelly和Kannade提出,现在基本上已经不用了,根据名字就可以得出,这个检测方法就是根据脸部的一些特征,比如眼睛的大小,鼻子的大小,眼睛到鼻子的距离等等一些基本特征点,所以说,它的优缺点也显而易见,识别简单,速度快,缺点却也很明显,每个人的脸部特征都是不一样的,没有办法做到非常准确,尤其是现在发展的人脸识别扫码支付,如果只是用特征检测,那么很有可能会导致识别错乱,造成不可估量的后果。但是也不是完全不能发展,现在的人来能识别都是二维的,并不能做到三维,如果说能够做到三维的识别,那么几何特征的识别将是非常出众的。


2.特征脸方法


MIT的Turk和Pentland在1991年提出的人脸识别算法,其实简单的来说,就是将识别到的脸放在一个目标空间中,和已经存在的人脸进行匹配,就是对于一个模板的匹配。优缺点肯定也很明显,优点就是快速,一旦匹配成功,就基本不会出错,缺点就是数据库中必须存在这个人脸模板,人脸识别的时候必须保持和数据库中的人脸模板具有相同的特征,识别效果差,可应用范围小。


具体的步骤如下:


(1)、将所有人脸图像变成Nx1的向量,然后将所有人脸向量组成矩阵M。
(2)、对矩阵M做归一化
(3)、求矩阵M的协方差矩阵C。
(4)、求协方差矩阵C的特征值和特征向量,并将最大的R个特征值对应的特征向量按行组成矩阵P,此时P就是算法希望找到的空间转换。


3.渔夫脸方法


由 Belhumeur提出,在特征脸的基础上,加入线性判别分析方法,该方法目前依旧是主流的人脸识别之一。基本思想就是同一人脸由于光照条件和角度变化带来的差异往往要大于不同人脸之间的差异,所以要将这些特征删除,方法就是应用线性判别分析,使得类内的散度最小。具体算法步骤:


(1)、将所有人脸图像变成Nx1的向量。
(2)、应用PCA降维(与特征脸方法类似),得到人脸向量。
(3)、对所有图像求平均值。
(4)、对每一类(同一人脸)做平均值得到:。
(5)、计算类间散度:,为i类的数量。
(6)、计算类内散度:。
(7)、对目标函数(投影矩阵)求极值:



#渔夫脸方法
import sys
import os
import cv2
import numpy as np
class SkinDetector():
    """
    对颜色空间取阈值
    """
    def _R1(self,BGR):
        B = BGR[:,:,0]
        G = BGR[:,:,1]
        R = BGR[:,:,2]
        e1 = (R>95) & (G>40) & (B>20) & ((np.maximum(R,np.maximum(G,B)) - np.minimum(R, np.minimum(G,B)))>15) & (np.abs(R-G)>15) & (R>G) & (R>B)
        e2 = (R>220) & (G>210) & (B>170) & (abs(R-G)<=15) & (R>B) & (G>B)
        return (e1|e2)
    def _R2(self,YCrCb):
        Y = YCrCb[:,:,0]
        Cr = YCrCb[:,:,1]
        Cb = YCrCb[:,:,2]
        e1 = Cr <= (1.5862*Cb+20)
        e2 = Cr >= (0.3448*Cb+76.2069)
        e3 = Cr >= (-4.5652*Cb+234.5652)
        e4 = Cr <= (-1.15*Cb+301.75)
        e5 = Cr <= (-2.2857*Cb+432.85)
        return e1 & e2 & e3 & e4 & e5
    def _R3(self,HSV):
        H = HSV[:,:,0]
        S = HSV[:,:,1]
        V = HSV[:,:,2]
        return ((H<25) | (H>230))
    def detect(self, src):
        if np.ndim(src) < 3:
            return np.ones(src.shape, dtype=np.uint8)
        if src.dtype != np.uint8:
            return np.ones(src.shape, dtype=np.uint8)
        srcYCrCb = cv2.cvtColor(src, cv2.COLOR_BGR2YCR_CB)
        srcHSV = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
        skinPixels = self._R1(src) & self._R2(srcYCrCb) & self._R3(srcHSV)
        return np.asarray(skinPixels, dtype=np.uint8)
class CascadedDetector():
    """
    利用OpenCV函数构建检测器,可调参数:scaleFactor、minNeighbors、minSize
    """
    def __init__(self, cascade_fn="C:\Users\Administrator\AppData\Local\Programs\python\Python310\Lib\site-packages\cv2\data\haarcascade_frontalface_alt2.xml", scaleFactor=1.2, minNeighbors=5, minSize=(30,30)):
        self.cascade = cv2.CascadeClassifier(cascade_fn)
        self.scaleFactor = scaleFactor
        self.minNeighbors = minNeighbors
        self.minSize = minSize
    def detect(self, src):
        if np.ndim(src) == 3:
            src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
        src = cv2.equalizeHist(src)
        rects = self.cascade.detectMultiScale(src,scaleFactor=self.scaleFactor, minNeighbors=self.minNeighbors, minSize=self.minSize)
        if len(rects) == 0:
            return np.ndarray((0,))
        rects[:,2:] += rects[:,:2]
        return rects
class SkinFaceDetector():
    """
    只接受与肤色相近的候选人脸
    """
    def __init__(self, threshold=0.3, cascade_fn='C:\Users\Administrator\AppData\Local\Programs\python\Python310\Lib\site-packages\cv2\data\haarcascade_frontalface_alt2.xml', scaleFactor=1.2, minNeighbors=5, minSize=(30,30)):
        self.faceDetector = CascadedDetector(cascade_fn=cascade_fn, scaleFactor=scaleFactor, minNeighbors=minNeighbors, minSize=minSize)
        self.skinDetector = SkinDetector()
        self.threshold = threshold
    def detect(self, src):
        rects = []
        for i,r in enumerate(self.faceDetector.detect(src)):
            x0,y0,x1,y1 = r
            face = src[y0:y1,x0:x1]
            skinPixels = self.skinDetector.detect(face)
            skinPercentage = float(np.sum(skinPixels)) / skinPixels.size
            print(skinPercentage)
            if skinPercentage > self.threshold:
                rects.append(r)
        return rects
if __name__ == "__main__":
    #输入图像
    if len(sys.argv) < 2:
        raise Exception("No image given.")
    inFileName = sys.argv[1]
    outFileName = None
    #输出目录
    if len(sys.argv) > 2:
        outFileName = sys.argv[2]
    if outFileName == inFileName:
        outFileName = None
    #开始检测
    img = np.array(cv2.imread('F:\Image\\test16.jpg'), dtype=np.uint8)
    imgOut = img.copy()
    detector = CascadedDetector(cascade_fn="C:\Users\Administrator\AppData\Local\Programs\python\Python310\Lib\site-packages\cv2\data\haarcascade_frontalface_alt2.xml")
    eyesDetector = CascadedDetector(scaleFactor=1.1,minNeighbors=5, minSize=(20,20), cascade_fn="C:\Users\Administrator\AppData\Local\Programs\python\Python310\Lib\site-packages\cv2\data\haarcascade_eye.xml")
    for i,r in enumerate(detector.detect(img)):
        x0,y0,x1,y1 = r
        cv2.rectangle(imgOut, (x0,y0),(x1,y1),(0,255,0),1)
        face = img[y0:y1,x0:x1]
        for j,r2 in enumerate(eyesDetector.detect(face)):
            ex0,ey0,ex1,ey1 = r2
            cv2.rectangle(imgOut, (x0+ex0,y0+ey0),(x0+ex1,y0+ey1),(0,255,0),1)
    #显示图片
    if outFileName is None:
        cv2.imshow('faces', imgOut)
        cv2.waitKey(0)
        cv2.imwrite(outFileName, imgOut)


4.基于弹性匹配


Wiskott于1997年使用Gabor小波对人脸图像进行处理,将人脸表达成由若干个 特征点构成的并具有一定拓扑结构信息的人脸弹性图。图的顶点代表关键特征点(Jet),边的属性则为不同特征点之间的关系。此方法用了全局特征,还用了局部特征。


什么叫Gabor小波?为什么要用Habor小波?


Gabor小波是以任意一个高斯函数作为窗口函数的波函数。一个图像像素与不同的Gabor核卷积后的系数集合称为一个Jet(一般为40个系数)。一个jet描述了一个像素周围一小块的灰度。


用Gabor小波的原因是因为Gabor小波对于亮度变化和人脸的不同表情不敏感,匹配精度大大提高。


搜索步骤:


(1)、对每个特征点,从图像中定位起粗略位置。
(2)、在以标准化的人脸图像中计算出处的Gabor变换系数。
(3)、将与模板中的特征点进行比较,其中相似度最高的为候选者,计算其位置误差,则特征点的精确位置修正为。
(4)、重复上述步骤,将最后的得到的精确点的求出Gaboe系数即可。


5.基于支持向量机(SVM)的方法


SVM在后面的专栏会做出详细的介绍,这里就不过多的介绍,SVM分类器训练为一个二分类器(人脸和非人脸),当然也可以每一类训练一个SVM分类器。其实就是利用分类器的特点进行匹配。


6. 基于神经网络的方法


基于神经网络的方法前面已经介绍过,不需要我们来提取特征点,只需要利用已经训练好的样本就可以,尤其是近年来深度学习的快速发展,神经网络的检测也越来越受到欢迎,不过缺点就是需要大量的训练。


深度学习方法


深度学习中对于图像的处理发展最快的就是卷积神经网络,所以对于人脸识别,大多数时候都采用卷积神经网络方法进行训练测试,但是深度学习是一个很复杂的知识脉络,这里不能很深渡的介绍,所以深度学习就放在另一个专栏中介绍,这里就只是简单的介绍一下。


神经网络训练模型有很多,比如GoogleNet、VGG16、YOLO等模型,他们的原理前面都介绍过了,神经网络基本上都差不多,所以他们的具体步骤就不过多介绍。主要就是其中卷积层,全连接层,池化层的操作,以及一些激活函数,损失函数,优化分类器的选择。下面就给出了一个示例,后面对于神经网络的搭建也会深度介绍。


#深度学习人脸识别方法
import os
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
import cv2
import numpy as np
from sklearn.model_selection import train_test_split
faces_path = '人脸数据集位置'
imgs = []
labels = []
#读取数据
for filename in os.listdir(faces_path):
    if filename.endswith('.jpg'):
        filename = path + '/' + filename
        img = cv2.imread(filename)
        imgs.append(img)
        labels.append(filename[-1])
#将图片数据与标签转换成数组
imgs = np.array(imgs)
labels = np.array(labels)
#划分训练集与测试集
train_x,test_x,train_y,test_y = train_test_split(imgs, labels, test_size=0.2)
#统一人脸图像大小
train_x = train_x.reshape(train_x.shape[0], 100, 100, 3)
test_x = test_x.reshape(test_x.shape[0], 100, 100, 3)
#归一化
train_x = train_x.astype('float32')/255.0
test_x = test_x.astype('float32')/255.0
batch_size = 64
num_batch = len(train_x) //batch_size
#网络
model = Sequential([
    Conv2D(32, 3, padding='same', activation='relu', input_shape=(100, 100,3)),
    MaxPooling2D(),
    Dropout(0.5)
    Conv2D(64, 3, padding='same', activation='relu'), 
    MaxPooling2D(),
    Dropout(0.5),
    Conv2D(64, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Dropout(0.5),
    Conv2D(64, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Dropout(0.5),
    Flatten(),
    Dense(256, activation='relu'),
    Dense(1, activation='sigmoid')
])
#编译模型,输入优化器、损失函数
model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])
#训练
model.fit(train_x, train_y,epoch=10, batchsize = 64)
#测试
model.eval(test_x, test_y)


好了,本节的只是就到此结束了,计算机视觉专栏也就到此结束了,后面就进入深度学习专栏了。由于博主能力有限,如果后面有其他知识,会补充到这里的。再见了!

相关文章
|
6月前
|
人工智能 API 数据安全/隐私保护
Azure AI - Azure人脸识别任务概述与技术实战
Azure AI - Azure人脸识别任务概述与技术实战
216 1
|
机器学习/深度学习 TensorFlow 算法框架/工具
人脸识别概述-opencv中文文档
人脸识别概述-opencv中文文档
133 0
|
6月前
|
弹性计算 Java PHP
新手用户注册阿里云账号、实名认证、购买云服务器图文教程参考
对于初次购买阿里云产品的用户来说,第一步要做的是注册账号并完成实名认证,然后才是购买阿里云服务器或者其他云产品,本文为大家以图文形式展示一下新手用户从注册阿里云账号、实名认证到购买云服务器完整详细教程,以供参考。
新手用户注册阿里云账号、实名认证、购买云服务器图文教程参考
|
5月前
|
文字识别 算法 API
视觉智能开放平台产品使用合集之uniapp框架如何使用阿里云金融级人脸识别
视觉智能开放平台是指提供一系列基于视觉识别技术的API和服务的平台,这些服务通常包括图像识别、人脸识别、物体检测、文字识别、场景理解等。企业或开发者可以通过调用这些API,快速将视觉智能功能集成到自己的应用或服务中,而无需从零开始研发相关算法和技术。以下是一些常见的视觉智能开放平台产品及其应用场景的概览。
137 0
|
机器学习/深度学习 搜索推荐 计算机视觉
【阿里云OpenVI-人脸感知理解系列之人脸识别】基于Transformer的人脸识别新框架TransFace ICCV-2023论文深入解读
本文介绍 阿里云开放视觉智能团队 被计算机视觉顶级国际会议ICCV 2023接收的论文 &quot;TransFace: Calibrating Transformer Training for Face Recognition from a Data-Centric Perspective&quot;。TransFace旨在探索ViT在人脸识别任务上表现不佳的原因,并从data-centric的角度去提升ViT在人脸识别任务上的性能。
2162 341
|
6月前
对于阿里云OpenAPI的域名实名认证
【1月更文挑战第5天】【1月更文挑战第22篇】对于阿里云OpenAPI的域名实名认证
78 1
|
安全 数据安全/隐私保护
阿里云账号注册、实名认证、账号信息管理、密码找回及账号注销流程及常见问题
本文为大家详细介绍我们在注册阿里云账号,完成账号实名认证,管理账号信息,账号密码找回以及注销账号的详细流程及常见问题。
阿里云账号注册、实名认证、账号信息管理、密码找回及账号注销流程及常见问题
|
人工智能 计算机视觉
阿里云产品体系分为6大分类——人工智能——分为10种模块——人脸识别
阿里云产品体系分为6大分类——人工智能——分为10种模块——人脸识别自制脑图
126 1
|
弹性计算 Java PHP
新手用户注册阿里云账号、实名认证、购买云服务器详细教程(图文教程)
在我们购买阿里云服务器等云产品之前,首先要做的就是注册账号并完成实名认证,之后才能购买阿里云服务器等各种云产品,购买之前如果碰到有最新优惠券或代金券可以领取,在购买过程中还可以使用优惠券或者代金券抵扣订单金额,减少购买成本。下面为大家以图文形式展示一下新手用户注册阿里云账号、实名认证、购买云服务器详细教程。
2535 0
新手用户注册阿里云账号、实名认证、购买云服务器详细教程(图文教程)

热门文章

最新文章