当前位置: 代码网 > it编程>游戏开发>ar > 基于flask+opencv+sklearn+tensorflow的人脸识别系统(一)

基于flask+opencv+sklearn+tensorflow的人脸识别系统(一)

2024年08月04日 ar 我要评论
近年以来,人工智能技术飞速发展,其主要分为鉴别和生成两个方面,其中人脸识别技术是其鉴别技术的重要分支,本文详细讲解使用opencv+sklearn+tensorflow技术,实现人脸识别的学习性项目。

近年以来,人工智能技术飞速发展,其主要分为鉴别和生成两个方面,其中人脸识别技术是其鉴别技术的重要分支,本文详细讲解使用opencv+sklearn+tensorflow技术,实现人脸识别的学习性项目。

一、系统功能分析

本项目具体功能模块如下所示:

1、采样样本照片

调用本地计算机摄像头采集照片作为样本,设置使用快捷键进行采样和取样,一次性可以多张照片,采样照片越多,人脸识别的成功率越高。

2、图片处理

将采集到原始图像转化为标准数据文件,即数据集。

3、深度学习

创建深度学习模型,学习训练、将训练结果保存为".h5"文件.

4、人脸识别

使用训练所得的模型实现人脸识别功能,即可以从本地摄像头识别,还可从网络摄像头识别。

二、系统流程分析

项目实现的流程如下所示:

三、技术分析

项目主要用到以下的框架:

(1)flask

典型的python web开发框架

(2)opencv-python

它是opencv的python接口,一个开源发行的跨平台计算机视觉库,轻量级且高效(由一系列c函数和少量c++类构成),提供python,rupy,matlab等语言的接口,实现图像处理和计算机视觉方面的通用算法。

(3)sklearn

机器学习中常用第三方模块,对常用机器学习方法进行封装,包括回归、降维、分类、聚类等方法。

(4)tensorflow

tensorflow是一个由google brain团队开发的开源机器学习框架。最初是作为google内部工具而开发的,但随后在2015年被开源,以便更广泛的社群能够利用和贡献于这个框架。tensorflow支持从研究到生产的全面工作流程,包括模型设计、训练、优化和部署。

四、框架安装

安装以上框架需要使用以下命令:

pip install flask   //安装flask框架

pip install opencv-python  //安装opencv-python框架

pip install scikit-learn  //安装sklearn框架

pip install tensorflow //安装tensoflow框架

五、照片样本采集

样本采集模块getcamerapics.py基本摄像头采集视频流中的数据,截取人脸照片作为样本并存储。具体代码如下:


import os
import cv2
import random
import numpy as np
from tensorflow.python.keras.utils import np_utils
from keras.models import sequential,load_model
from keras.layers import dense,activation,convolution2d,maxpooling2d,flatten,dropout
from sklearn.model_selection import train_test_split

def cameraautoforpictures(savedir='data/'):
    "调用计算机摄像头来自动获取图片"
    if not os.path.exists(savedir):
        os.makedirs(savedir)
    count=1
    cap=cv2.videocapture(0)
    width,height,w=640,480,360
    cap.set(cv2.cap_prop_frame_width,width)
    cap.set(cv2.cap_prop_frame_height,height)
    crop_w_start=(width-w)//2
    crop_h_start=(height-w)//2
    print('width:',width)
    print('height:',height)
    while true:
        ret,frame=cap.read()
        frame=frame[crop_h_start:crop_h_start+w,crop_w_start:crop_w_start+w]
        frame=cv2.flip(frame,1,dst=none)
        cv2.imshow("capture",frame)
        action=cv2.waitkey(1)&0xff
        if action==ord('c'):
            savedir=input(u"请输入新的存储目录:")
            if not os.path.exists(savedir):
                os.makedirs(savedir)
        elif action==ord('p'):
            cv2.imwrite("%s/%d.jpg" % (savedir,count),cv2.resize(frame,(224,224),interpolation=cv2.inter_area))
            print(u"%s:%d张图片" % (savedir,count))
            count+=1
        if action==ord('q'):
                    break
    cap.release()
    cv2.destroyallwindows()

if __name__=='__main__':
    cameraautoforpictures(savedir='data/guanxi/')

通过上述代码,启动摄像头后借助键盘完成图片获取操作,其中按键C(change)表示设置一个存储样本照片的目录,按键p(photo)表示执行截图操作,按键q(quit)表示退出拍摄。运行后打开计算机本地摄像头,按下键盘中p会截取照片,并保存在data/guanxi/目录中。

六、深度学习和训练

处理样本照片,形成数据集,构建卷积网络模型并使用数据集进行训练,将训练后的模型保存为“.h5"模型文件,根据模型文件实现人脸识别。

1、原始图像预处理

原始图像预处理代码文件datahelper.py如下:

import os
import cv2
import time

def readallimg(path,*suffix):
    "基于后缀读取文件"
    try:
        s=os.listdir(path)
        resultarray=[]
        for i in s :
            if endwith(i,suffix):
                document=os.path.join(path,i)
                img=cv2.imread(document)
                resultarray.append(img)
    except ioerror:
        print("error")
    else:
        print("读取成功")
        return resultarray
    
def endwith(s,*endstring):
    "对字符串的后续和标签进行匹配" 
    resultarray=map(s.endswith,endstring)
    if true in resultarray:
        return true
    else:
        return false
        

def readpicsaveface(sourcepath,objectpath,*suffix):
    "图片标准化存储"
    if not os.path.exists(objectpath):
        os.makedirs(objectpath)
    try:
        resultarray=readallimg(sourcepath,*suffix)
        count=1
        face_cascade=cv2.cascadeclassifier('config/haarcascade_frontalface_alt.xml')
        for i in resultarray:
            if type(i)!=str:
                gray=cv2.cvtcolor(i,cv2.color_bgr2gray)
                faces=face_cascade.detectmultiscale(gray,1.1,5)
                print(faces)
                for (x,y,w,h) in faces:
                    liststr=[str(int(time.time()))]
                    filename=".join(liststr)"
                    f=cv2.resize(gray[y:(y+h),x:(x+w)],(200,200))
                    cv2.imwrite(objectpath+os.sep+'%s.jpg'%filename,f)
                    count+=1
    except exception as e :
        print("exception: ",e)
    else:
        print("read "+str(count-1)+' faces to destination'+objectpath)

if __name__=='__main__':
    print('dataprocessing!!!')
    readpicsaveface('data/guanxi/','dataset/chengsongtao/','jpg','jpg','png','png','tiff')

代码首先检测是否存在标准化存储目录,如无则创建之,其次读入所有样本图片,使用opencv自带的人脸检测haarcascade_frontalface_alt.xml分类器获取人脸定位,并保存为大小为200*200大小的灰度图像。opencv-python的分类器在lib/site-page/data文件夹中,复制相应的分类器并保存在项目目录下的config文件夹中,其中cv2.cascadeclassifier.detectmultiscale() 函数各个参数及返回值的含义为:

        image:待检测图像,通常为灰度图像。
        scalefactor:表示在前后两次相继的扫描中,搜索窗口的缩放比例。
        minneighbors:表示构成检测目标的相邻矩形的最小个数。默认情况下,该值为 3,意味着有 3 个以上的检测标记存在时,才认为人脸存在。如果希望提高检测的准确率,可以将该值设置得更大,但同时可能会让一些人脸无法被检测到。
        flags:该参数通常被省略。在使用低版本 opencv(opencv 1.x 版本)时,它可能会被设置为 cv_haar_do_canny_pruning,表示使用 canny 边缘检测器来拒绝一些区域。
        minsize:目标的最小尺寸,小于这个尺寸的目标将被忽略。
        maxsize:目标的最大尺寸,大于这个尺寸的目标将被忽略。
        objects:返回值,目标对象的矩形框向量组。

如果需要处理多人的样本图片,需要在__main__下添加多个对应的的处理目录,运行上述文件后,会在dataset目录下得到处理后照片。

2、数据集处理类

编写faceregnitionmodel.py文件,功能是通过深度学习和训练构建人脸识别模块,将训练后得到的模型文件face.h5保存在本地。类dataset是保存和读取格式化后的训练数据,具体代码如下:

class dataset(object):
    def __init__(self,path):
        "初始化"
        self.num_classes=none
        self.x_train=none
        self.x_test=none
        self.y_train=none
        self.y_test=none
        self.img_size=128
        self.extract_data(path)
    
    def read_file(self,path):
        img_list=[]
        label_list=[]
        dir_counter=0
        img_size=128
        for child_dir in os.listdir(path):
            child_path=os.path.join(path,child_dir)
            for dir_image in os.listdir(child_path):
                if dir_image.endswith('jpg'):
                    img=cv2.imread(os.path.join(child_path,dir_image))
                    resized_img=cv2.resize(img,(img_size,img_size))
                    recolored_img=cv2.cvtcolor(resized_img,cv2.color_bgr2gray)
                    img_list.append(recolored_img)
                    label_list.append(dir_counter)
            dir_counter+=1
        img_list=np.array(img_list)
        return img_list,label_list,dir_counter
    
    def extract_data(self,path):
        imgs,labels,counter=self.read_file(path)
x_train,x_test,y_train,y_test=train_test_split(imgs,labels,test_size=0.2,random_state=random.randint(0,100))
        x_train=x_train.reshape(x_train.shape[0],1,self.img_size,self.img_size)/255.0
        x_test=x_test.reshape(x_test.shape[0],1,self.img_size,self.img_size)/255.0
        x_train=x_train.astype('float32')
        x_test=x_test.astype('float32')
        y_train=np_utils.to_categorical(y_train,num_classes=counter)
        y_test=np_utils.to_categorical(y_test,num_classes=counter)

        self.x_train=x_train
        self.x_test=x_test
        self.y_train=y_train
        self.y_test=y_test
        self.num_classes=counter
  
    def check(self):
        "校验"
        print('num of dim :',self.x_test.ndim)
        print('shape: ',self.x_test.shape)
        print('size: ',self.x_test.size)
        print('num of dim : ',self.x_train.ndim)
        print('shape: ',self.x_train.shape)
        print('size: ',self.x_train.size)
    
    def read_name_list(self,path):
        name_list=[]
        for child_dir in os.listdir(path):
            name_list.append(child_dir)
        return name_list

函数extract_data()抽取数据,使用机器学习sklearn中的函数train_test_split将原始数据集按照一定比例划分训练集和测试集对模型进行训练,通过reshape()将图片转换成128*128的灰度图像,通过函数astype()将图片转换为float32数据类型。其中train_test_split()函数原型如下所示:

train_test_split(train_data,train_target,test_size,random_state)

各参数具体说明如下:

        train_data: 表示被划分的样本特征集

        train_target:表示划分的样本标签

        test_size: 表示样本按比例划分,返回第的第一个参数值为train_data*test_size

        random_state:表示随机种子,当为整数时,不管循环多少次x_train与第一次相同,其值不能为小数。

函数check(self)实现数据校验,打印输出图片的基本信息,函数read_file(self,path) 读取指定路径的图片信息。函数read_name_list(self,path)读取训练数据集。

3、模型构建与训练

类model创建一个基于cnn的人脸识别模型,开始构建数据模型并进行训练,具体代码如下:

class model(object):
    "人脸识别模型"
    file_path="face.h5"
    image_size=128

    def __init__(self):
        self.model=none

    def read_traindata(self,dataset):
        self.dataset=dataset
    
    def build_model(self):
        self.model=sequential()
        self.model.add(
            convolution2d(
                filters=32,
                kernel_size=(5,5),
                padding='same',
                input_shape=self.dataset.x_train.shape[1:]
            )
        )
        self.model.add(activation('relu'))
        self.model.add(
            maxpooling2d(
                pool_size=(2,2),
                strides=(2,2),
                padding='same'
            )
        )
        self.model.add(
            convolution2d(
                filters=64,
                kernel_size=(5,5),
                padding='same'
            )
        )
        self.model.add(activation('relu'))
        self.model.add(
            maxpooling2d(
                pool_size=(2,2),
                strides=(2,2),
                padding='same'
            )
        )
        self.model.add(flatten())
        self.model.add(dense(1024))
        self.model.add(activation('relu'))
        self.model.add(dense(self.dataset.num_classes))
        self.model.add(activation('softmax'))
        self.model.summary()
    
    def train_model(self):
         self.model.compile(
             optimizer='adam',
             loss='categorical_crossentropy',
             metrics=['accuracy'] )
         self.model.fit(self.dataset.x_train,self.dataset.y_train,epochs=10,batch_size=10)
    
    def evaluate_model(self):
        print('\ntesting--------------')
        loss,accuracy=self.model.evaluate(self.dataset.x_test,self.dataset.y_test)
        print('test loss: ', loss)
        print('test accuracy: ',accuracy)
    
    def save(self,file_path=file_path):
        print('model saved finished!!!')
        self.model.save(file_path)
    
    def load(self,file_path=file_path):
        print('model loaded successful!!!')
        self.model=load_model(file_path)
    
    def predict(self,img):
        img=img.reshape((1,1,self.image_size,self.image_size))
        img=img.astype('float32')
        img=img/255.0
        result=self.model.predict_proba(img)
        max_index=np.argmax(result)
        return max_index.result[0][max_index]

类model创建一个基于cnn的人脸识别模型,其模型结构如下所示:

模型输入为1*128*128,训练、评估、保存效果如下所示:

调用上面的函数,打印输出模型训练和评估结果,具体的代码如下:

if __name__=='__main__':
    dataset=dataset('dataset/')
    model=model()
    model.read_traindata(dataset)
    model.build_model()
    model.train_model()
    model.evaluate_model()
    model.save()

七、人脸识别

使用人工智能技术实现深度学习后,生成一个数据模型文件, 通过调用这个模型文件可以实现人脸识别功能,实例camerademp.py文件,通过opencv-python直接调用摄像头实现人脸识别功能,代码如下所示:

from faceregnitionmodel import  model

threshold=0.7  #如果模型认为概率高于70%则显示为模型中已有的人物

def read_name_list(path):
    "读取训练数据集"
    name_list=[]
    for child_dir in os.listdir(path):
        name_list.append(child_dir)
    return name_list

class camera_reader(object):    
    def __init__(self):
        self.model=model()
        self.model.load()
        self.img_size=128
    
    def build_camera(self):
        "调用摄像头实现实时人脸识别"
        name_list=read_name_list('dataset/')
        cameracapture=cv2.videocapture(0)
        face_cascade=cv2.cascadeclassifier('config/haarcascade_frontalface_alt.xml')
        while true:
            ret,frame=cameracapture.read()
            gray=cv2.cvtcolor(frame,cv2.color_bgr2gray)
            faces=face_cascade.detectmultiscale(gray,1.05,5) 
            for (x,y,w,h) in faces:
                roi=gray[x:x+w,y:y+h]
                roi=cv2.resize(roi,(self.img_size,self.img_size),interpolation=cv2.inter_linear)
                label,prob=self.model.predict(roi)                          
                if prob>threshold:
                    show_name=name_list[label]
                else:
                    show_name="stranger"
                cv2.puttext(frame,show_name,(x,y-20),cv2.font_hershey_simplex,1,255,2)
                frame=cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
            cv2.imshow("capture",frame)
            action=cv2.waitkey(1)&0xff
            if action==ord('q'):
                break     
       
        cameracapture.release()
        cv2.destroyallwindows()
              
if __name__=='__main__':
    camera=camera_reader()
    camera.build_camera()

具体的执行逻辑是先开启摄像头,再获取视频帧 ,最后是调用脸部检测分类器,获取脸部视频帧区域参数 ,调用模型进行识别并在原帧上进行标记。执行后会开启摄像头并识别人物且进行标记。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com