基于深度学习的人脸识别系统实战

人工智能与算法云原生可观测

picture.image

作者:沂水寒城,CSDN博客专家,个人研究方向:机器学习、深度学习、NLP、CV

Blog: http://yishuihancheng.blog.csdn.net

人脸识别如今已经是家喻户晓了,几乎每天都要跟他打交道,我们上班的考勤机就是一个人脸识别系统,我们俗称“刷脸机”。进入火车站或者机场的时候也会有人脸识别的需要,这里面都是深度学习的计算力在支撑,今天主要的内容是自己动手完整地去实践整个人脸识别系统,虽说人脸识别已经不是很新鲜的东西了,但是对于一个数据挖掘从业者或者初学者来说想要完整地做出来一个属于自己的人脸识别项目还是需要花费一定的时间去学习摸索的。

项目整体架构示意图如下所示:

picture.image

项目中我们使用到的数据集一共有两个来源,一部分是来源于网上公开可用的人脸识别数据集,可以节省我们数据获取的时间和成本,方便直接进行实验处理,另一部分是基于电脑的摄像头来进行自身人脸数据的收集,这个可以用来训练可以识别我们自己的模型,因为人脸识别本质是一个分类问题,这还是很有意思的。

接下来我们针对上面的流程进行详细的说明与实现讲解:

一、人脸识别数据集获取

这里我们使用到公开网络数据集我记得是一个小批量的日本的人脸数据,数据集一共包含了10个类别,截图如下所示:

picture.image

这里需要的话直接上网搜索即可,就不再多做说明了,下面针对自身人脸数据采集进行说明。

具体的代码实现如下所示:


        
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=raw_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()   

    

启动之后,可以借助键盘操作实现快速截图保存等操作,具体操作方法如下所示:

picture.image

完成了数据集创建工作后就可以进行后续的工作了。

二、图像数据标准化处理

该部分主要是对上一部分获取到的图像数据做标准化的处理,具体的代码实现如下所示:


        
def readPicSaveFace(sourceDir,objectDir,*S):  
    '''  
    图片标准化与存储  
    '''  
    if not os.path.exists(objectDir):  
        os.makedirs(objectDir)  
    try:  
        resultArray=readAllImg(sourceDir,*S)  
        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.3, 5)  
              for (x,y,w,h) in faces:  
                listStr=[str(int(time.time())),str(count)]    
                fileName=''.join(listStr)  
                f=cv2.resize(gray[y:(y+h),x:(x+w)],(200, 200))  
                cv2.imwrite(objectDir+os.sep+'%s.jpg' % fileName, f)  
                count+=1  
    except Exception as e:  
        print("Exception: ",e)  
    else:  
        print('Read  '+str(count-1)+' Faces to Destination '+objectDir)  

    

简单的调用如下所示:


        
readPicSaveFace('data/KA/','dataset/KA/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/KL/','dataset/KL/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/KM/','dataset/KM/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/KR/','dataset/KR/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/MK/','dataset/MK/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/NA/','dataset/NA/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/NM/','dataset/NM/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/TM/','dataset/TM/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/UY/','dataset/UY/','.jpg','.JPG','png','PNG','tiff')  
readPicSaveFace('data/YM/','dataset/YM/','.jpg','.JPG','png','PNG','tiff')  

    

完成后,标准化的图像数据就存储在了dataset文件夹下面,这就是我们的数据集。

三、CNN识别模型搭建

对于接触过深度学习的人来说这一部分应该是比较熟悉的了,所以这里我就不再进行过多的说明,直接看实现代码如下:


        
class Model(object):  
    '''  
    人脸识别模型  
    '''  
    FILE_PATH="faceModel.h5"    
    IMAGE_SIZE=128    
  
  
    def \_\_init\_\_(self):  
        self.model=None  
  
  
    def build\_model(self):  
        self.model = Sequential()  
        self.model.add(  
            Convolution2D(  
                filters=32,  
                kernel_size=(5, 5),  
                padding='same',  
                dim_ordering='th',  
                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):  
        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]  

    

我将识别模型封装成了一个可以直接使用的类,需要的话可以直接实例化进行调用。

到这里,我们的模型创建工作就结束了。训练完成后我们就得到了可以离线使用的人脸识别模型faceModel.h5,这个文件可以持久化存储之后可以一直使用。

四、接口开发与测试

该部分主要是基于flask模块来开发人脸识别的接口,比较简单,直接看代码实现如下所示:


        
@app.route("/")  
def init():  
    '''  
    初始化接口    
    http://IP:5000  
    '''  
    return u"人脸识别程序正常启动!"  
  
  
@app.route("/detect", methods=["GET"])  
def detectFace():  
    '''  
    人脸识别接口    
    http://IP:5000/detect?picture=155062779317.jpg  
    '''  
    if request.method=="GET":   
        picture=request.args['picture']  
    start_time=time.time()  
    res=detectOnePicture(picture)  
    end_time=time.time()  
    execute_time=str(round(end_time-start_time,2))  
    tsg=u' 总耗时为: %s 秒' % execute_time  
    msg=res+'\n\n'+tsg  
    return msg  

    

简单看一下具体的测试结果,测试图片如下所示:

picture.image

类别KA

到这里本文的工作就结束了,很高兴在自己温习回顾知识的同时能写下点分享的东西出来,如果说您觉得我的内容还可以或者是对您有所启发、帮助,还希望得到您的鼓励支持,谢谢!

赞 赏 作 者

picture.image

Python中文社区作为一个去中心化的全球技术社区,以成为全球20万Python中文开发者的精神部落为愿景,目前覆盖各大主流媒体和协作平台,与阿里、腾讯、百度、微软、亚马逊、开源中国、CSDN等业界知名公司和技术社区建立了广泛的联系,拥有来自十多个国家和地区数万名登记会员,会员来自以工信部、清华大学、北京大学、北京邮电大学、中国人民银行、中科院、中金、华为、BAT、谷歌、微软等为代表的政府机关、科研单位、金融机构以及海内外知名公司,全平台近20万开发者关注。

picture.image

▼ 点击成为 社区注册会员 「在看」 一下,一起PY

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
DevOps 在字节移动研发中的探索和实践
在日益复杂的APP工程架构下,如何保证APP能高效开发,保障团队效能和工程质量?本次将结合字节内部应用的事件案例,介绍DevOps团队对移动研发效能建设的探索和思考。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论