欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

人脸口罩数据集的模型训练以及戴口罩识别检测

程序员文章站 2022-07-13 10:18:55
...

一.理解人脸图像特征的各种方法

1)方向梯度直方图

方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。HOG特征通过计算和统计图像局部区域的梯度方向直方图来构成特征。

1、主要思想:

在一副图像中,局部目标的表象和形状能够被梯度或边缘的方向密度分布很好地描述。其本质为:梯度的统计信息,而梯度主要存在于边缘的地方。

Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。

2、实现方法:

首先将图像分成小的连通区域,这些连通区域被叫做细胞单元。然后采集细胞单元中各像素点的梯度的或边缘的方向直方图。最后把这些直方图组合起来,就可以构成特征描述符。

3、性能提高:

将这些局部直方图在图像的更大的范围内(叫做区间)进行对比度归一化,可以提高该算法的性能,所采用的方法是:先计算各直方图在这个区间中的密度,然后根据这个密度对区间中的各个细胞单元做归一化。通过这个归一化后,能对光照变化和阴影获得更好的效果。

HOG特征的提取与计算步骤

HOG特征的具体提取步骤如下

人脸口罩数据集的模型训练以及戴口罩识别检测HOG特征提取的流程图

1、色彩和伽马归一化

为了减少光照因素的影响,首先需要将整个图像进行规范化(归一化)。在图像的纹理强度中,局部的表层曝光贡献的比重较大,所以,这种压缩处理能够有效地降低图像局部的阴影和光照变化。

2、计算图像梯度

计算图像横坐标和纵坐标方向的梯度,并据此计算每个像素位置的梯度方向值;求导操作不仅能够捕获轮廓,人影和一些纹理信息,还能进一步弱化光照的影响。

最常用的方法是:简单地使用一个一维的离散微分模板在一个方向上或者同时在水平和垂直两个方向上对图像进行处理,更确切地说,这个方法需要使用滤波器核滤除图像中的色彩或变化剧烈的数据

3、构建方向的直方图

细胞单元中的每一个像素点都为某个基于方向的直方图通道投票。

人脸口罩数据集的模型训练以及戴口罩识别检测星型细胞单元

投票是采取加权投票的方式,即每一票都是带有权值的,这个权值是根据该像素点的梯度幅度计算出来。可以采用幅值本身或者它的函数来表示这个权值,实际测试表明: 使用幅值来表示权值能获得最佳的效果,当然,也可以选择幅值的函数来表示,比如幅值的平方根、幅值的平方、幅值的截断形式等。细胞单元可以是矩形的,也可以是星形的。直方图通道是平均分布在0-1800(无向)或0-3600(有向)范围内。经研究发现,采用无向的梯度和9个直方图通道,能在行人检测试验中取得最佳的效果。

4、将细胞单元组合成大的区间

由于局部光照的变化以及前景-背景对比度的变化,使得梯度强度的变化范围非常大。这就需要对梯度强度做归一化。归一化能够进一步地对光照、阴影和边缘进行压缩。

人脸口罩数据集的模型训练以及戴口罩识别检测R-HOG

采取的办法是:把各个细胞单元组合成大的、空间上连通的区间。这样,HOG描述符就变成了由各区间所有细胞单元的直方图成分所组成的一个向量。这些区间是互有重叠的,这就意味着:每一个细胞单元的输出都多次作用于最终的描述器。

区间有两个主要的几何形状——矩形区间(R-HOG)和环形区间(C-HOG)

人脸口罩数据集的模型训练以及戴口罩识别检测C-HOG

。R-HOG区间大体上是一些方形的格子,它可以有三个参数来表征:每个区间中细胞单元的数目、每个细胞单元中像素点的数目、每个细胞的直方图通道数目。

5、收集HOG特征

把提取的HOG特征输入到SVM分类器中,寻找一个最优超平面作为决策函数。

2)dlib

Dlib人脸特征检测原理

(1)提取特征点

(2)获取特征数据集写入csv

(3)计算特征数据集的欧氏距离作对比

shape_predictor_68_face_landmarks.dat是已经训练好的人脸关键点检测器。

dlib_face_recognition_resnet_model_v1.dat是训练好的ResNet人脸识别模型。

68特征原理人脸关键点检测

人脸对齐(Face Alignment)基本概念及原理

基本概念:人脸识别(face recognizaton)按顺序可以大体上分为四个部分,即人脸检测(face detection),人脸对齐(face alignment),人脸校验(face verification)和人脸识别(face identification)。 人脸检测就是在一张图片中找到人脸所处的位置,即将人脸圈出来,比如拍照时数码相机自动画出人脸。人脸对齐就是在已经检测到的人脸的基础上,自动找到人脸上的眼睛鼻子嘴和脸轮廓等标志性特征位置。人脸校验就是判断两张脸是不是同一个人。人脸识别就是给定一张脸,判断这张脸是谁。

人脸对齐中的几个关键词:
形状(shape):形状就是人脸上的有特征的位置,如下图所示,每张图中所有黄点构成的图形就是该人脸的形状。
特征点(landmark):形状由特征点组成,图中的每一个黄点就是一个特征点。

人脸对齐的最终目的就是在已知的人脸方框(一般由人脸检测确定人脸的位置)上定位其准确地形状。
人脸对齐的算法主要分为两大类:基于优化的方法(Optimization-based method)和基于回归的方法(Regression-based method)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-COd7OdIl-1594042094105)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200630200327674.png)]

3)卷积神经网络

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一 。卷积神经网络具有表征学习(representation learning)能力,能够按其阶层结构对输入信息进行平移不变分类(shift-invariant classification),因此也被称为“平移不变人工神经网络(Shift-Invariant Artificial Neural Networks, SIANN)”

对卷积神经网络的研究始于二十世纪80至90年代,时间延迟网络和LeNet-5是最早出现的卷积神经网络 ;在二十一世纪后,随着深度学习理论的提出和数值计算设备的改进,卷积神经网络得到了快速发展,并被应用于计算机视觉、自然语言处理等领域 。

卷积神经网络仿造生物的视知觉(visual perception)机制构建,可以进行监督学习和非监督学习,其隐含层内的卷积核参数共享和层间连接的稀疏性使得卷积神经网络能够以较小的计算量对格点化(grid-like topology)特征,例如像素和音频进行学习、有稳定的效果且对数据没有额外的特征工程(feature engineering)要求

Python3+Dlib+Opencv实现摄像头采集人脸并对表情进行实时分类判读
一. dlib以及opencv-python库安装
1.1 dlib库安装
1.2 opencv-python库安装
二.dlib的68点模型
三.Python实现摄像头人脸检测
3.1 python代码
3.2 运行结果
一. dlib以及opencv-python库安装
1.1 dlib库安装
在Anaconda Prompt下输入以下命令

pip install dlib

如果下载失败,可能是网速太慢,多试几次即可。但如果始终不行可以用另一种安装方法
首先需要从网上下载
dlib:http://dlib.net/ 或者 https://github.com/davisking/dlib
下载完成后,解压缩

人脸口罩数据集的模型训练以及戴口罩识别检测

2、编译
->打开终端,并且定位在dlib文件夹,使用python setup.py install产生上面的文件夹
在运行上面的命令时可能会遇见以下两种问题:
①在运行的时候会出现找不到cmake的问题
解决方法:
当遇见这个问题的时候,说明你的系统环境中并没有cmake,所以这时候需要你在你的电脑上安装cmake编译环境。
->官网下载安装包:https://cmake.org/download/

->下载完成之后,解压缩,然后将cmake的bin文件夹添加在系统环境路径中。

->添加环境变量

->然后将这两个文件复制到boost_1_66_0根文件夹下:
->同样开启一个命令行,定位到这个文件夹,运行命令:
b2 install
->利用b2编译库文件:
b2 -a –with-python address-model=64 toolset=msvc runtime-link=static
->之前你cmake下载的64位这里(address-model)写64,如果是32位的就把之前的64改成32
->然后将boost添加到环境变量中:
③运行完成之后,重新运行python setup.py install
3、耐心等待,即可获得上面的dlib中的两个文件夹
4、将其添加到python的lib中:
—>例如我的python环境为python2.7,
—>所以将其放在python2-7文件夹的Python2-7\Lib\site-packages中
—>这时,就已经完成了dlib的配置

二.dlib的68点模型
dlib的68点模型,使用网络上大神训练好的特征预测器,用来进行python代码人脸识别的特征预测。
我已经将其上传至CSDN,有需要的同学可以直接点击链接下载face.dat。

三.Python实现摄像头人脸检测
3.1 python代码
Python实现摄像头人脸检测并对表情进行实时分类判读,python代码如下:

“”"
从视屏中识别人脸,并实时标出面部特征点
“”"

import sys
import dlib  # 人脸识别的库dlib
import numpy as np  # 数据处理的库numpy
import cv2  # 图像处理的库OpenCv

class face_emotion():
    def __init__(self):
        # 使用特征提取器get_frontal_face_detector
        self.detector = dlib.get_frontal_face_detector()
        # dlib的68点模型,使用作者训练好的特征预测器
        self.predictor = dlib.shape_predictor("face.dat")
    # 建cv2摄像头对象,这里使用电脑自带摄像头,如果接了外部摄像头,则自动切换到外部摄像头
    self.cap = cv2.VideoCapture(0)
    # 设置视频参数,propId设置的视频参数,value设置的参数值
    self.cap.set(3, 480)
    # 截图screenshoot的计数器
    self.cnt = 0
 
def learning_face(self):
 
    # 眉毛直线拟合数据缓冲
    line_brow_x = []
    line_brow_y = []
 
    # cap.isOpened() 返回true/false 检查初始化是否成功
    while (self.cap.isOpened()):
 
        # cap.read()
        # 返回两个值:
        #    一个布尔值true/false,用来判断读取视频是否成功/是否到视频末尾
        #    图像对象,图像的三维矩阵
        flag, im_rd = self.cap.read()
 
        # 每帧数据延时1ms,延时为0读取的是静态帧
        k = cv2.waitKey(1)
 
        # 取灰度
        img_gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY)
 
        # 使用人脸检测器检测每一帧图像中的人脸。并返回人脸数rects
        faces = self.detector(img_gray, 0)
 
        # 待会要显示在屏幕上的字体
        font = cv2.FONT_HERSHEY_SIMPLEX
 
        # 如果检测到人脸
        if (len(faces) != 0):
 
            # 对每个人脸都标出68个特征点
            for i in range(len(faces)):
                # enumerate方法同时返回数据对象的索引和数据,k为索引,d为faces中的对象
                for k, d in enumerate(faces):
                    # 用红色矩形框出人脸
                    cv2.rectangle(im_rd, (d.left(), d.top()), (d.right(), d.bottom()), (0, 0, 255))
                    # 计算人脸热别框边长
                    self.face_width = d.right() - d.left()
 
                    # 使用预测器得到68点数据的坐标
                    shape = self.predictor(im_rd, d)
                    # 圆圈显示每个特征点
                    for i in range(68):
                        cv2.circle(im_rd, (shape.part(i).x, shape.part(i).y), 2, (0, 255, 0), -1, 8)
                        # cv2.putText(im_rd, str(i), (shape.part(i).x, shape.part(i).y), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                        #            (255, 255, 255))
 
                    # 分析任意n点的位置关系来作为表情识别的依据
                    mouth_width = (shape.part(54).x - shape.part(48).x) / self.face_width  # 嘴巴咧开程度
                    mouth_higth = (shape.part(66).y - shape.part(62).y) / self.face_width  # 嘴巴张开程度
                    # print("嘴巴宽度与识别框宽度之比:",mouth_width_arv)
                    # print("嘴巴高度与识别框高度之比:",mouth_higth_arv)
 
                    # 通过两个眉毛上的10个特征点,分析挑眉程度和皱眉程度
                    brow_sum = 0  # 高度之和
                    frown_sum = 0  # 两边眉毛距离之和
                    for j in range(17, 21):
                        brow_sum += (shape.part(j).y - d.top()) + (shape.part(j + 5).y - d.top())
                        frown_sum += shape.part(j + 5).x - shape.part(j).x
                        line_brow_x.append(shape.part(j).x)
                        line_brow_y.append(shape.part(j).y)
 
                    # self.brow_k, self.brow_d = self.fit_slr(line_brow_x, line_brow_y)  # 计算眉毛的倾斜程度
                    tempx = np.array(line_brow_x)
                    tempy = np.array(line_brow_y)
                    z1 = np.polyfit(tempx, tempy, 1)  # 拟合成一次直线
                    self.brow_k = -round(z1[0], 3)  # 拟合出曲线的斜率和实际眉毛的倾斜方向是相反的
 
                    brow_hight = (brow_sum / 10) / self.face_width  # 眉毛高度占比
                    brow_width = (frown_sum / 5) / self.face_width  # 眉毛距离占比
                    # print("眉毛高度与识别框高度之比:",round(brow_arv/self.face_width,3))
                    # print("眉毛间距与识别框高度之比:",round(frown_arv/self.face_width,3))
 
                    # 眼睛睁开程度
                    eye_sum = (shape.part(41).y - shape.part(37).y + shape.part(40).y - shape.part(38).y +
                               shape.part(47).y - shape.part(43).y + shape.part(46).y - shape.part(44).y)
                    eye_hight = (eye_sum / 4) / self.face_width
                    # print("眼睛睁开距离与识别框高度之比:",round(eye_open/self.face_width,3))
 
                    # 分情况讨论
                    # 张嘴,可能是开心或者惊讶
                    if round(mouth_higth >= 0.03):
                        if eye_hight >= 0.056:
                            cv2.putText(im_rd, "amazing", (d.left(), d.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX,
                                        0.8,
                                        (0, 0, 255), 2, 4)
                        else:
                            cv2.putText(im_rd, "happy", (d.left(), d.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8,
                                        (0, 0, 255), 2, 4)
 
                    # 没有张嘴,可能是正常和生气
                    else:
                        if self.brow_k <= -0.3:
                            cv2.putText(im_rd, "angry", (d.left(), d.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8,
                                        (0, 0, 255), 2, 4)
                        else:
                            cv2.putText(im_rd, "nature", (d.left(), d.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8,
                                        (0, 0, 255), 2, 4)
 
            # 标出人脸数
            cv2.putText(im_rd, "Faces: " + str(len(faces)), (20, 50), font, 1, (0, 0, 255), 1, cv2.LINE_AA)
        else:
            # 没有检测到人脸
            cv2.putText(im_rd, "No Face", (20, 50), font, 1, (0, 0, 255), 1, cv2.LINE_AA)
 
        # 添加说明
        im_rd = cv2.putText(im_rd, "S: screenshot", (20, 400), font, 0.8, (0, 0, 255), 1, cv2.LINE_AA)
        im_rd = cv2.putText(im_rd, "Q: quit", (20, 450), font, 0.8, (0, 0, 255), 1, cv2.LINE_AA)
 
        # 按下s键截图保存
        if (k == ord('s')):
            self.cnt += 1
            cv2.imwrite("screenshoot" + str(self.cnt) + ".jpg", im_rd)
 
        # 按下q键退出
        if (k == ord('q')):
            break
 
        # 窗口显示
        cv2.imshow("camera", im_rd)
 
    # 释放摄像头
    self.cap.release()
 
    # 删除建立的窗口
    cv2.destroyAllWindows()
if __name__ == "__main__":
    my_face = face_emotion()
    my_face.learning_face()

3.2 运行结果

二、人脸口罩数据集的下载及处理

数据下载地址

划分测试集、训练集以及验证集

同时测试集、验证集以及训练集中都需要创建保存笑脸与非笑脸的文件夹,这个还挺重要的。因为创建的这两个文件夹就会作为后面的label,也就是说比如我创建一个smile与unsmile文件夹,之后训练过后,我们可以打出来smile与unsmile代表的含义,这也就是label。因此做这个,一定要分好类。

这里给出之前猫狗数据集划分的代码

# The path to the directory where the original
# dataset was uncompressed
#测试集
original_dataset_dir = 'datasets/kaggle/train/'

# The directory where we will
# store our smaller dataset
#创建的文件夹
base_dir = 'datasets/猫狗数据'
os.mkdir(base_dir)

# Directories for our training,
# validation and test splits
#会在猫狗数据文件夹下创建train、test、validation三个文件夹
train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir, 'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_dir, 'test')
os.mkdir(test_dir)

# Directory with our training cat pictures
#train文件夹下创建cats和dogs文件夹
train_cats_dir = os.path.join(train_dir, 'cats')
os.mkdir(train_cats_dir)

# Directory with our training dog pictures
train_dogs_dir = os.path.join(train_dir, 'dogs')
os.mkdir(train_dogs_dir)

# Directory with our validation cat pictures
#validation文件夹下创建cats和dogs文件夹
validation_cats_dir = os.path.join(validation_dir, 'cats')
os.mkdir(validation_cats_dir)

# Directory with our validation dog pictures
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
os.mkdir(validation_dogs_dir)

# Directory with our validation cat pictures
#test文件夹下创建cats文件夹和dogs文件夹
test_cats_dir = os.path.join(test_dir, 'cats')
os.mkdir(test_cats_dir)

# Directory with our validation dog pictures
test_dogs_dir = os.path.join(test_dir, 'dogs')
os.mkdir(test_dogs_dir)

# Copy first 1000 cat images to train_cats_dir

#复制猫图片
fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(train_cats_dir, fname)
    shutil.copyfile(src, dst)

# Copy next 500 cat images to validation_cats_dir
fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(validation_cats_dir, fname)
    shutil.copyfile(src, dst)
    
# Copy next 500 cat images to test_cats_dir
fnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(test_cats_dir, fname)
    shutil.copyfile(src, dst)
    
# Copy first 1000 dog images to train_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(train_dogs_dir, fname)
    shutil.copyfile(src, dst)
    
# Copy next 500 dog images to validation_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(validation_dogs_dir, fname)
    shutil.copyfile(src, dst)
    
# Copy next 500 dog images to test_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(test_dogs_dir, fname)
    shutil.copyfile(src, dst)

创建模型

#创建模型
from keras import layers
from keras import models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
                        input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

对图片进行归一化处理

from keras import optimizers

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])
from keras.preprocessing.image import ImageDataGenerator
# All images will be rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
validation_datagen=ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        # 目标文件目录
        train_dir,
        #所有图片的size必须是150x150
        target_size=(150, 150),
        batch_size=20,
        # Since we use binary_crossentropy loss, we need binary labels
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=20,
        class_mode='binary')
test_generator = test_datagen.flow_from_directory(test_dir,
                                                   target_size=(150, 150),
                                                   batch_size=20,
                                                   class_mode='binary')

未进行数据增强时进行训练模型

画出训练集与验证集的精确度与损失度的图形

import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()

人脸口罩数据集的模型训练以及戴口罩识别检测

三、摄像头采集自己人脸、并对表情作出判断。

import cv2
from keras.preprocessing import image
from keras.models import load_model
import numpy as np
import dlib
from PIL import Image
model = load_model('data/mask/maskAndNomask_2.h5')
detector = dlib.get_frontal_face_detector()
# video=cv2.VideoCapture('media/video.mp4')
# video=cv2.VideoCapture('data/face_recognition.mp4')
video=cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_SIMPLEX
def rec(img):
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    dets=detector(gray,1)
    if dets is not None:
        for face in dets:
            left=face.left()
            top=face.top()
            right=face.right()
            bottom=face.bottom()
            cv2.rectangle(img,(left,top),(right,bottom),(0,255,0),2)
def mask(img):
    img1=cv2.resize(img,dsize=(150,150))
    img1=cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
    img1 = np.array(img1)/255.
    img_tensor = img1.reshape(-1,150,150,3)
    prediction =model.predict(img_tensor)    
    if prediction[0][0]>0.5:
        result='no-mask'
    else:
        result='have-mask'
    cv2.putText(img, result, (100,200), font, 2, (0, 255, 0), 2, cv2.LINE_AA)
    cv2.imshow('Video', img)          
while video.isOpened():
    res, img_rd = video.read()
    if not res:
        break
    #将视频每一帧传入两个函数,分别用于圈出人脸与判断是否带口罩
    rec(img_rd)
    mask(img_rd)
    #q关闭窗口
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
video.release()
cv2.destroyAllWindows()

人脸口罩数据集的模型训练以及戴口罩识别检测
人脸口罩数据集的模型训练以及戴口罩识别检测
人脸口罩数据集的模型训练以及戴口罩识别检测

#检测视频或者摄像头中的人脸

# 这个是截取到的每一帧 在截取出人脸部分送入检测  但是带了口罩过后会识别不出人脸  有问题,最后没有用这个来检测

import cv2
from keras.preprocessing import image
from keras.models import load_model
import numpy as np
import dlib
from PIL import Image

model = load_model('data/CNN口罩识别/maskAndNomask_2.h5')
detector = dlib.get_frontal_face_detector()

# video=cv2.VideoCapture('media/video.mp4')
# video=cv2.VideoCapture('data/face_recognition.mp4')
video=cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_SIMPLEX
def rec(img):
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    dets=detector(gray,1)
    if dets is not None:
        for face in dets:
            left=face.left()
            top=face.top()
            right=face.right()
            bottom=face.bottom()
            cv2.rectangle(img,(left,top),(right,bottom),(0,255,0),2)
    #         img1=img[top:bottom,left:right]

            img1=cv2.resize(img[top:bottom,left:right],dsize=(150,150))
            img1=cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
            #     img1=img.reshape(1, 150, 150, 3)
            # im = Image.fromarray(img1)
            #     print(type(im))
            #img_tensor = image.img_to_array(im)/255.0
            img1 = np.array(img1)/255.
            img_tensor = img1.reshape(-1,150,150,3)
            # img_tensor = np.expand_dims(img_tensor, axis=0)
            prediction =model.predict(img_tensor)    
            #     print(prediction)
            if prediction[0][0]>0.5:
                result='no-mask'
            else:
                result='have-mask'
            cv2.putText(img, result, (100,200), font, 2, (0, 255, 0), 2, cv2.LINE_AA)
        cv2.imshow('Video', img)
while video.isOpened():
    res, img_rd = video.read()
    if not res:
        break
    rec(img_rd)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
video.release()
cv2.destroyAllWindows()

人脸口罩数据集的模型训练以及戴口罩识别检测