CNN人脸识别项目(dlib+opencv)

2023-11-09


思路:一个CNN人脸识别项目首先必不可少的是数据集,获取的方式有网站数据库 PubFig:Public Figures Face Database、Large-scale CelebFaces Attribtes(CelebA) Dataset、BioID Face Database-FaceDB、YouTube Face等网站,或者是自己根据需求在网页抓取图像并进行图像的一些预处理操作
然后是建立一个model用于训练数据集,根据精度大小判断网络模型的好坏
最后就是选取一个图片或者一个批次图片进行测试,并对其进行可视化

获取数据集

这里首先以PubFig:Public Figures Face Database网站的数据集格式进行讲解,然后再选取自己的图片进行替换即可,不要问为什么不自己弄,一是拿来主义多好理解就行,而是人家是多少团队搞出来的肯定比自己制定的标准吧
开始正文:
在网站下载的数据集包括person Name.txt和url.txt两个文件,person Name.txt用于存储所有人脸图像的名字,类似标签文本,url.txt文件则包括人名、图片序号、URL地址、人脸坐标和MD5校验码
在这里插入图片描述
在这里插入图片描述

现在就需要对数据集进行处理了,因为网络模型需要的是标签和图像,标签有了,图像需要我们根据url.txt中的URl地址进行抓取了,然后将抓取的图像进行分类,根据不同人名建立文件夹进行存储获取到原始图片newddata,但是训练模型要求的其实人脸,所以还需要在原始图片上截取人脸,因为url.txt已经含有截取后的人脸坐标直接进行读取得到cutdata

cutdata
newdata
**具体代码如下:**
from urllib.request import urlretrieve
from urllib import request
from PIL import Image
import requests
import urllib
import socket
import re
import cv2
import os
import time
import random
import datetime

# 设置请求头
def get_headers():
    '''
    随机获取一个headers
    '''
    user_agents = [
                    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.3578.80 Safari/537.36',
                    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
                    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
                    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'           
                    ]
    headers = ('User-Agent', random.choice(user_agents))
    print(headers)
    return headers


headers = ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36")

# 定义代理ip
# proxy_addr="128.199.81.214:12357"
# 
proxy_addr = "138.197.196.222"
post = '13499'
# #设置代理
# proxy=urllib.request.ProxyHandler({'http':proxy_addr})

proxy = urllib.request.ProxyHandler({'http':(proxy_addr + ':' + post)})

# 创建一个opener
opener = request.build_opener()
# 将headers添加到opener中
opener.addheaders = [headers]
# 将opener安装为全局
request.install_opener(opener)
# 用urlopen打开网页
# data=urllib.request.urlopen(url).read().decode('utf-8','ignore')

# 设定一下无响应时间,防止有的坏图片长时间没办法下载下来,10秒
timeout = 10000
socket.setdefaulttimeout(timeout)


#自定义一个下载进度函数,然后urlretrieve中赋值给reporthook参数即可
def callbackfunc(blocknum, blocksize, totalsize):
    '''回调函数
    @blocknum: 已经下载的数据块
    @blocksize: 数据块的大小
    @totalsize: 远程文件的大小
    '''
    time_stamp = datetime.datetime.now()
    percent = 100.0 * blocknum * blocksize / totalsize
    if percent > 100 or percent < 0 :
        percent = 100
    print("已完成:%.2f%%" % percent + "     " + time_stamp.strftime('%Y.%m.%d-%H:%M:%S'))


# 处理文件数据
# 从文件中读取人名和url
pic_data = []
with open('ch09\9 FaceRecognition\src\Preunder\data/url.txt') as f:
    for i in f.readlines():
        pic_data.append(i.strip('\r\n'))

new_data = []
for data in pic_data:
    if len(data.split()) == 6:
        name, surname, _, url, coord, _ = data.split()  # 名,姓,图片数量,url,人脸坐标,md5校验和
        new_data.append(name + ' ' + surname + ' ' + url + ' ' + coord)  # 返回 name surname+url+coord

# 写入到文件里面
with open('ch09\9 FaceRecognition\src\Preunder\data/urlAdd.data', 'w') as f:
    for i in new_data:
        f.write(i)
        f.write('\n')

# 从文件里面读:名,姓,url,人脸坐标
pic_data = []
with open('ch09\9 FaceRecognition\src\Preunder\data/urlAdd.data') as f:
    for i in f.readlines():
        pic_data.append(i.strip('\r\n'))

# 从文件里面读名字
names = []
with open('ch09\9 FaceRecognition\src\Preunder\data/personName.txt') as f:
    for i in f.readlines():
        names.append(i.strip('\r\n'))
# print(names[1])
num = 0
sucess = 0
for name in names:
#     print('name:' + name)
    # 创建保存原图目录
    if os.path.exists('../Preunder/data/newdata/' + name) == False:  # 判断文件夹是否存在
        # 不存在,创建文件夹
        os.mkdir('D:\wendang/vscode\CV/face_opencv\ch09\9 FaceRecognition\src\Preunder\data/newdata/' + name)
    # 创建中间量图片
    if os.path.exists('../Preunder/data/middata/' + name) == False:  # 判断文件夹是否存在
        # 不存在,创建文件夹
        os.mkdir('D:\wendang/vscode\CV/face_opencv\ch09\9 FaceRecognition\src\Preunder\data\middata/' + name)                 
    # 创建保存截取图像目录
    if os.path.exists('../Preunder/data/cutdata/' + name) == False:  # 判断文件夹是否存在
        # 不存在,创建文件夹
        os.mkdir('D:\wendang/vscode\CV/face_opencv\ch09\9 FaceRecognition\src\Preunder\data\cutdata/' + name)                 
#   print('========================================')
    count = 200
    for data in pic_data:
        pname, surname, url, coord = data.split()  # 名,姓,url,坐标
        url = str(url)
        coords = []
        coords = coord.split(',')
#         print('+++++++++++++'+name.split()[0]+ ' ' +name.split()[1])
        if pname == name.split()[0] and surname == name.split()[1]:
#             print(name.split()[0] + ';' + pname + ';' + name.split()[1] + ';' + surname)
            print('name:' + pname + ' ' + surname + '           count:%d' %(count-200))                              
            # 通过urllibs的requests获取所有的图片
            try:
                # 获取图片并保存到本地文件夹
                print(url)
                time_stamp = datetime.datetime.now()
                print("当前时间:" + time_stamp.strftime('%Y.%m.%d-%H:%M:%S'))
                
                print('saving.......') 
                
                pic = urlretrieve(url=url, filename='../Preunder/data/newdata/' + name + '/%d.jpg' % count, reporthook=callbackfunc)
                     
                print(pname + ' ' + surname + ': picture %d' %(count - 200))
                # 截取图片
                print('cuting.......')
                image = Image.open('../Preunder/data/newdata/' + name + '/%d.jpg' % count)
#               image = cv2.imread('../Preunder/data/newdata/' + name + '/%d.jpg' % count)  #从指定路径读取图像
#               cropImg = image[coords[0]:coords[2],coords[1]:coords[3]]    #截取指定脸部
                img = image.crop((int(coords[0]), int(coords[1]), int(coords[2]), int(coords[3])))
                img.save('../Preunder/data/middata/' + name + '/%d.jpg' % count)  # 保存图片为中间图片
#               cv2.imwrite("C:\\Users\\Desktop\\qwe\\",cropImg)     #保存到指定目录
                faceimage = cv2.imread('../Preunder/data/middata/' + name + '/%d.jpg' % count)  # 从指定路径读取图像
                  
                '''
                                    经过测试后得到脸部数据均小于128*128,
                                    所以暂时把灰度化和脸部截取统一大小改为后期进行或修改大小:64*64
                '''               
                  
                # 检查是否符合,符合则保存(128*128)  =>(64*64)
                sp = faceimage.shape  # 获取宽,高,深(深度有0-3,灰度-三种原色)
                print('recuting.......')
                if sp[0] > 128 and sp[1] > 128:    
                    gray = cv2.cvtColor(faceimage, cv2.COLOR_BGR2GRAY)  # 灰度化
                    face = cv2.resize(gray, (128, 128), interpolation=cv2.INTER_CUBIC)  # 设置截图大小并截取
                    cv2.imwrite('../Preunder/data/cutdata/' + name + '/%d.jpg' % count, face)  
                    print('save cutPic.......')
                else:
                    print("图片尺寸太小")
                sucess += 1
                count += 1
#                 time.sleep(random.randint(3, 10))  # 暂停5~10秒的整数秒,时间区间:[5,10]
            except Exception as e:
                print(Exception, ':', e)
                num += 1
                # 重新设置信息
                post = random.randint(139, 16000)
                proxy = urllib.request.ProxyHandler({'http':(proxy_addr + ':' + str(post))})
                opener = request.build_opener()
                # 将headers添加到opener中
                opener.addheaders = [get_headers()]
                # 将opener安装为全局
                request.install_opener(opener)
        else:
            count = 200  # 采取新人图像,初始化count
    
    # 输出一共采集成功数目和失败数目 
    print('采集对象  =====>>%s 成功次数:%d , 失败次数:%d' % (name, sucess, num))       
 
if __name__ == '__main__':
    get_headers()

以上代码看似很多其实很多是为了可视化美观,真正内容就根据url.txt图片url是抓取图片、建立人名文件夹放入对应图片,并根据url.txt人脸坐标信息将人脸图片同样放到人名文件里得到训练集图片

如果训练自己的图片数据集可以按照以上格式先建立相应的原始图片文件夹,然后利用dlib框架来检测人脸得到每个人名的人脸图片

首先读取自己设置的所有的原始图片newdata到列表里
这里的读取图片的前提是已经建立newdata文件夹,且里面包含不同人名的子文件夹,每个文件夹包含对应人名的原始图片,且每次只能读取一个人名类别的所有图片,如果想一次性读取所有人名类别的文件夹则需要优化部分代码

import os
import cv2


#根据输入的文件夹绝对路径,将该文件夹下的所有指定suffix的文件读取存入一个list,该list的第一个元素是该文件夹的名字
def readAllImg(path,*suffix):
    try:

        s = os.listdir(path)
        resultArray = []
        fileName = os.path.basename(path)
        resultArray.append(fileName)

        for i in s:
            if endwith(i, *suffix):
                document = os.path.join(path, i)
                img = cv2.imread(document)
                resultArray.append(img)
                
    except IOError:
        print("读取失败!")

    else:
        print("读取成功!")
        return resultArray

#输入一个字符串一个标签,对这个字符串的后续和标签进行匹配
def endwith(s,*endstring):
    resultArray = map(s.endswith,endstring)
    # if True in resultArray:
    #     return True
    # else:
    #     return False
    return resultArray

if __name__ == '__main__':

    result = readAllImg("ch09\shuju\LeiFeng_",'.jpg')
    print (result[0])
    cv2.namedWindow("Image")
    cv2.imshow("Image", result[1])
    cv2.waitKey(0)
    cv2.destroyAllWindows()

然后对图片检测人脸得到图片放入cutdata文件

import os
import cv2
import dlib
import time
from readImage import readAllImg

#从源路径中读取所有图片放入一个list,然后逐一进行检查,把其中的脸扣下来,存储到目标路径中
def readPicSaveFace(sourcePath,objectPath,*suffix):
    try:
        #读取照片,注意第一个元素是文件名
        resultArray=readAllImg(sourcePath,*suffix)

        #对list中图片逐一进行检查,找出其中的人脸然后写到目标文件夹下

        count = 1
#         face_cascade = cv2.CascadeClassifier('D:\opencv\sources\data\haarcascades\haarcascade_frontalface_alt.xml')
        # 使用detector进行人脸检测
        # 使用dlib自带的frontal_face_detector作为我们的特征提取器
        detector = dlib.get_frontal_face_detector()
        for i in resultArray:
            if type(i) != str:
                gray = cv2.cvtColor(i, cv2.COLOR_BGR2GRAY)
#                 faces = face_cascade.detectMultiScale(gray, 1.3, 5)
                dets = detector(gray, 1) # 提取截图中所有人脸
                for i, d in enumerate(dets): # 依次区分截图中的人脸
                    x1 = d.top() if d.top() > 0 else 0
                    y1 = d.bottom() if d.bottom() > 0 else 0
                    x2 = d.left() if d.left() > 0 else 0
                    y2 = d.right() if d.right() > 0 else 0
                    listStr = [str(int(time.time())), str(count)]  #以时间戳和读取的排序作为文件名称
                    fileName = ''.join(listStr)
 
                    f = cv2.resize(gray[x1:y1, x2:y2], (128, 128))  #设置截图大小并截取
                    cv2.imwrite(objectPath+os.sep+'%s.jpg' % fileName, f)
                    count += 1
                
#                 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)], (128, 128))  #设置截图大小并截取
#                     cv2.imwrite(objectPath+os.sep+'%s.jpg' % fileName, f)
#                     count += 1


    except IOError:
        print("Error")

    else:
        print('Already read '+str(count-1)+' Faces to Destination '+objectPath)

if __name__ == '__main__':
    # 从文件里面读名字
#     names = []
#     with open('../src//name.txt') as f:
#         for i in f.readlines():
#             names.append(i.strip('\r\n'))
#     for name in names:
#         print(name)
#         readPicSaveFace('../src/Preunder/data/middata/' + name,
#                     '../src/Preunder/data/cutdata/' + name,
#                     '.jpg','.JPG','png','PNG')
    readPicSaveFace('ch09\shuju\LeiFeng',
                    'ch09\shuju\LeiFeng_',
                    '.jpg','.JPG','png','PNG')

读取数据集

将制定好的不同人名文件夹存储不同的人脸gray图片(128*128大小)读取文件名也就是人名作为标签和人脸图像作为数据

import os
import cv2
import numpy as np

from readImage import endwith

#输入一个文件路径,对其下的每个文件夹下的图片读取,并对每个文件夹给一个不同的Label
#返回一个img的list,返回一个对应label的list,返回一下有几个文件夹(有几种label)

def readFile(path):
    img_list = []    #图片
    label_list = []  #标签
    dir_counter = 0  #子目录夹数
    IMG_SIZE = 128   #截取脸部大小

    #对路径下的所有子文件夹中的所有jpg文件进行读取并存入到一个list中
#     COUNT = 1
    for child_dir in os.listdir(path):
        child_path = os.path.join(path, child_dir)
#         count = 1
#         print('子文件夹:'+ child_path)
        for dir_image in  os.listdir(child_path):
            if endwith(dir_image,'jpg','JPG','png','PNG'):
                img = cv2.imread(os.path.join(child_path, dir_image))
                cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)
#                 ROTTT = img.shape
#                 print(ROTTT[0])
#                 print(ROTTT[1])
#                 print(ROTTT[2])
#                 print('count:%d'%count)
                recolored_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ## 图片转为灰度图 
#                 count +=1 
#                 recolored_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)         #灰度化图像
                resized_img = cv2.resize(recolored_img, (IMG_SIZE, IMG_SIZE))  #截取脸部  
                img_list.append(resized_img)
                label_list.append(dir_counter)

        dir_counter += 1

    # 返回的img_list转成了 np.array的格式
    img_list = np.array(img_list)

    return img_list,label_list,dir_counter

#因为我们是把同一个人的脸部图像放到一个文件夹里
#所以,文件夹名称是识别脸部的简单方法,后面会采用信息数据库进行数据的存储
#读取训练数据集的文件夹,把他们的名字返回给一个list
def readNameList(path):
    nameList = []
    for child_dir in os.listdir(path):
        nameList.append(child_dir)
    return nameList



if __name__ == '__main__':
    img_list,label_list,counter = readFile('ch09\9 FaceRecognition\images')  #文件夹下几个子文件夹
    print(label_list)

数据预处理

将读取到的label与imgs、类别数继进行预处理
也即train_test_split划分数据集 ,对图片进行归一化,对标签进行二进制化

from readData import readFile
from sklearn.model_selection import train_test_split
from keras.utils import np_utils
import random
# import os
# # 
# #临时改变底层神经网络使用theano搭建
# os.environ['KERAS_BACKEND'] = 'tensorflow'
# 
import keras.backend as K
#  
# K.set_image_dim_ordering('tf')


#建立一个用于存储和格式化读取训练数据的类
class modelDataSet(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     #128*128
        self.extract_data(path) #在这个类初始化的过程中读取path下的训练数据

    def extract_data(self,path):
        #根据指定路径读取出图片、标签和类别数
        imgs,labels,counter = readFile(path)
#         print(labels)
        #将数据集打乱随机分组,交叉验证中常用的函数,功能是从样本中随机的按比例选取train data和testdata
        #train_data:所要划分的样本特征集;train_target:所要划分的样本结果;test_size:样本占比,如果是整数的话就是样本的数量;random_state:是随机数的种子。
        X_train,X_test,y_train,y_test = train_test_split(imgs,labels,test_size=0.2,random_state=random.randint(0, 100))

        #重新格式化和标准化(或正常化), theano和tensorflow有很大的差别
        
        if K.image_data_format() == 'channels_first':
            #基于Theano
            X_train = X_train.reshape(X_train.shape[0], 1, self.img_size, self.img_size)/255.0  #数值为0-255,除以255图像化为0-1之间
            X_test = X_test.reshape(X_test.shape[0], 1, self.img_size, self.img_size) / 255.0
        else:
            #基于TensorFlow
            X_train = X_train.reshape(X_train.shape[0], self.img_size, self.img_size, 1)/255       #数值为0-255,除以255图像化为0-1之间
            X_test = X_test.reshape(X_test.shape[0], self.img_size, self.img_size, 1)/255
         
        
        X_train = X_train.astype('float32')    #指定数据类型为float32
        X_test = X_test.astype('float32')

        #将labels转成二进制矩阵
        Y_train = np_utils.to_categorical(y_train, num_classes=counter) #标签变为counter个长度 用十个长度举例:1:01;2:10
        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)

建立模型进行预训练

from modelDataSet import modelDataSet
from keras.models import Sequential,load_model
from keras.layers import Dense,Activation,Conv2D,MaxPooling2D,Flatten,Dropout
from keras.optimizers import *
import numpy as np




#建立一个基于CNN的人脸识别模型
class trainFaceModel(object):
    FILE_PATH = "ch09\9 FaceRecognition\image\model/model1.h5"   #模型进行存储和读取的地方
    IMAGE_SIZE = 128    #图片是64*64的

    def __init__(self):
        self.model = None

    #读取实例化后的modelDataSet类作为进行训练的数据源
    def read_trainData(self,modeldataset):
        self.modeldataset = modeldataset

    #建立一个CNN模型,一层卷积、一层池化、一层卷积、一层池化、抹平之后进行全连接、最后进行分类
    def build_model(self):
        #1.建立model:Sequential为按顺序建立model(一层一层来)
        self.model = Sequential()
        #标准卷积公式:Convolution1D主要用于nlp,Convolution2D主要用于cv
        #表面上Convolution1D没有给出卷积的大小,Convolution2D给出了
        
        #第一层
        self.model.add(
            Conv2D(
                filters=64,          #滤波器数量,最后出现多少层特征
                kernel_size=(4, 4), #row,low
                padding='same',      #padding(边界)模式,为"valid"或"same"
#                 dim_ordering='th',   #指明底层backend是theano(th)还是TensorFlow(tf)
                #作为第一层需提供input_shape参数
                input_shape=self.modeldataset.X_train.shape[1:]  
            )
        )
        self.model.add(Activation('relu'))  #激活
        self.model.add(
            MaxPooling2D(
                pool_size=(2, 2),  #向下取样多长多宽
                strides=(2, 2),    #跳的长度和宽度
                padding='same'     #padding(边界)模式,为"valid"或"same"
            )
        )
        
        #第二层
        self.model.add(
            Conv2D(
                filters=128, 
                kernel_size=(4, 4), 
                padding='same')
            )       
        self.model.add(Activation('relu'))
        self.model.add(MaxPooling2D(
            pool_size=(2, 2), 
            strides=(2, 2),
            padding='same'
            )
        )
                     
        #,第一个全连接层
        #把N维抹平为一维
        self.model.add(Flatten())
        #输入batch_size*row*col=1568,输出512,输出为自己设置的
        self.model.add(Dense(2048))
        self.model.add(Activation('relu'))
        
        #第二个全连接层,输出:self.modeldataset.num_classes
        self.model.add(Dense(self.modeldataset.num_classes))
        #分类
        self.model.add(Activation('softmax'))
        self.model.summary()
    #添加指标获取想要的信息
    def train_model(self):
        #定义优化器的另一种方法
#         rmsprop = RMSprop(lr=0.001,rho=0.9,epsilon=1e-08,decay=0.0)  #可以改参数
        #自定义损失函数
        self.model.compile(
            optimizer='adam',  #优化器
#             optimizer=rmsprop,  #优化器
            #目标函数,即损失函数,binary_crossentropy:对数损失
            #categorical_crossentropy:多类的对数损失,需将标签转化为形如(nb_samples, nb_classes)的二值序列
            loss='categorical_crossentropy',  
            metrics=['accuracy'])

        #epochs、batch_size为可调的参数,epochs为训练多少轮、batch_size为每次训练多少个样本
        self.model.fit(self.modeldataset.X_train,self.modeldataset.Y_train,epochs=3,batch_size=10)
    #使用前面的度量来评估模型
    def evaluate_model(self):
        print('\n测试中---------------')
        loss, accuracy = self.model.evaluate(self.modeldataset.X_test, self.modeldataset.Y_test)

        print('测试损失度:', loss)          
        print('测试精准度:', accuracy)
        return loss,accuracy

    def save(self, file_path=FILE_PATH):
        print('Model保存.')
        self.model.save(file_path)

    def load(self, file_path=FILE_PATH):
        print('Model加载.')
        self.model = load_model(file_path)

    #需要确保输入的img得是灰化之后(channel =1 )且 大小为IMAGE_SIZE的人脸图片
    def predict(self,img):
        img = img.reshape((1, self.IMAGE_SIZE, self.IMAGE_SIZE,1))#Reshape层用来将输入shape转换为特定的shape
        img = img.astype('float32')
        img = img/255.0    #标准化

        result = self.model.predict_proba(img)  #测算一下该img属于某个label的概率
        max_index = np.argmax(result) #找出概率最高的

        return max_index,result[0][max_index] #第一个参数为概率最高的label的index,第二个参数为对应概率


if __name__ == '__main__':
    modelDataSet = modelDataSet('ch09\9 FaceRecognition\images')
    model = trainFaceModel()
    model.read_trainData(modelDataSet)
    model.build_model()
    model.train_model()
    model.evaluate_model()
    model.save()

对图片进行人脸进行检测并进行可视化

可以对一个图片或者批次的图片进行检测,在人脸检测时可以利用dlib或者opencv的级联检测器都可以这里选择dlib

from readData import readNameList,readFile
from trainFaceModel import trainFaceModel
import dlib
import cv2
detector = dlib.get_frontal_face_detector()
face_cascade = cv2.CascadeClassifier('D:\miniconda\envs\py3.6\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml') 
IMAGE_SIZE = 128

def test_onePicture(path):
    model= trainFaceModel()
    model.load()
    img = cv2.imread(path)
    #检测里的人脸并标记
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ## 图片转为灰度图            
    dets = detector(gray, 1) # 提取截图中所有人脸
    for i, d in enumerate(dets): # 依次区分截图中的人脸
        x1 = d.top() if d.top() > 0 else 0
        y1 = d.bottom() if d.bottom() > 0 else 0
        x2 = d.left() if d.left() > 0 else 0
        y2 = d.right() if d.right() > 0 else 0
        
        ROI = gray[x1:y1, x2:y2]
        ROI = cv2.resize(ROI, (IMAGE_SIZE, IMAGE_SIZE), interpolation=cv2.INTER_LINEAR)
        label,prob = model.predict(ROI)  #利用模型对cv2识别出的人脸进行比对
        if prob >0.775:
            name_list = readNameList('ch09\9 FaceRecognition\images')
            print(name_list[label],prob)
            cv2.putText(img, name_list[label]+":"+str(prob), (x2, x1), cv2.FONT_HERSHEY_SIMPLEX, 1, (150, 200, 56), 2)  #显示名字
            cv2.rectangle(img, (x2, x1), (y2, y1), (150, 200, 56), 2)  #在人脸区域画一个正方形出来
        else:
            print("无法识别此人!")
    #显示起来
    cv2.imshow('Image', img)
    cv2.waitKey(0) & 0xff
    cv2.destroyAllWindows()
#     img = cv2.resize(img, (128, 128))
#     img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#     picType,prob = model.predict(img)
#     if picType != -1:
#         name_list = readNameList('../src/Preunder/data/cutdata')
#         print(name_list[picType],prob)
#         return name_list[picType],prob
#     else:
#         print("无法识别此人!")
#         return "无法识别此人!"

#读取文件夹下子文件夹中所有图片进行识别
def test_onBatch(path):
    model= trainFaceModel()
    model.load()
    index = 0
    img_list, label_list, counter = readFile(path)
    for img in img_list:
        picType,prob = model.predict(img)
        if picType != -1:
            index += 1
            name_list = readNameList('ch09\9 FaceRecognition\images')
            print(name_list[picType])
        else:
            print("无法识别此人!")

    return index

if __name__ == '__main__':
    test_onePicture('ch09\shuju/testima\LeiFengTest.jpg')

运行结果得到
在这里插入图片描述

总结

总体设计思路可以用以下流程图表示
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CNN人脸识别项目(dlib+opencv) 的相关文章

随机推荐

  • 使用Python的Cufflinks库创建三维散点图

    使用Python的Cufflinks库创建三维散点图 在数据可视化中 三维散点图是一种常用的图形展示方式 如果您正在寻找一种方便易用的数据可视化工具来创建三维散点图 那么Cufflinks就是一个不错的选择 Cufflinks是一个基于pl
  • 恕我直言,自从用完Gradle后,有点嫌弃Maven了!速度贼快!

    点击上方蓝色字体 选择 标星公众号 优质文章 第一时间送达 99套Java企业级实战项目 4000G架构师资料 作者 乐百川 点击阅读原文前往 授权转载自 toutiao com i6824937779193971207 相信使用Java的
  • Spring 基于ApplicationEvent、ApplicationEventPublisher、ApplicationListener的事件监听、发布记录

    1 概述 事件发布和订阅具体流程 1 具体要发布的事件 事件中携带发送的数据 2 发送事件 3 监听器 监听发布的事件 获取事件的携带数据 执行业务逻辑 发布 事件作为参数 事件 监听 事件作为参数 例如 使用切面记录系统日志 发送相同类型
  • oracle 9i在线重定义,Oracle 9i中表的在线重定义(转)

    今天遇到要把数据库中的某张表改成分区表 而且该表在别的地方还有其他的注册信息 如果自己手工建一个分区表的替代该表的话 那就得要手工地去执行该表在其他地方的注册 所以不想删除该表再手工创建同名的分区表 想到了Oracle 9i中可以使用在线重
  • gitee上传代码方法(命令)

    第一次上传 创建一个gitee仓库 在 我的电脑 里找到你要上传的文件的位置 在地址栏输入cmd 回车 输入git init 输入git add 输入git commit m 备注信息可更改 输入 git remote add origin
  • C语言中的清屏函数(自己编写)

    在csdn论坛里看到这样一个问题 如何在c语言命令提示下清除屏幕 感兴趣 随查之 有解 include
  • 蓝帽杯半决赛2022

    手机取证 1 iPhone手机的iBoot固件版本号 答案参考格式 iBoot 1 1 1 直接通过盘古石取证 打开 取证大师和火眼不知道为什么都无法提取这个 手机取证 2 该手机制作完备份UTC 8的时间 非提取时间 答案参考格式 200
  • 修炼离线:(五)hbase映射表插入hive

    一 创建hive表 sql drop table if exists ods odsyyy create table if not exists ods odsfff row id string comment 行记录唯一ID 对应ROW
  • Makefile入门二、理解$@、$^和$<

    文章目录 一 理解 lt 的含义 二 举例 三 简提Makefile中打印日志信息 前面简单记录了一下Makefile中helloworld的用法 这次来理解一些 lt 的含义 一 理解 lt 的含义 Makefile中 格式为这样的 ta
  • Spring Roo 实站( 一 )部署安装 & 第一个示例程序

    一 安装 注 可以参与官网spring roo static springsource org spring roo reference html intro html intro exploring sampleROO OPTS http
  • 【Linux 驱动篇(二)】LED 驱动开发

    文章目录 一 Linux 下 LED 灯驱动原理 1 地址映射 1 1 ioremap 函数 1 2 iounmap 函数 2 I O 内存访问函数 2 1 读操作函数 2 2 写操作函数 二 实验程序编写 1 LED 灯驱动程序编写 2
  • 电脑不能开热点的一种可以尝试的解决方法

    1 说明 方法不一定万能 个人情况 win10 以前可以开热点 不知何时起不能再开 会显示 我们无法设置移动热点 2 解决办法 1 管理员方式打开cmd 2 运行命令 netsh int ip reset netsh winsock res
  • 【金融系列】【statsmodels】如何用Python做实证研究?介绍一个功能和STATA很像的Python包,最小二乘,虚拟变量

    博主本科接触的研究主要是公司金融方向的研究 在公司金融的实证研究中 我们的终极目标是建立变量间的因果关系 我们需要识别因果关系 来检验理论 评价政策效果 或作出预测 目前该领域的研究大部分是使用了STATA和R这两种工具来开展研究的 其实作
  • 亲测可用:opencv图片序列转视频

    亲测可用 glob函数可以遍历文件夹下文件 完毕后可在项目目录下生成output avi视频 可以稍作改进 转换的时候显示当前转换图像 include
  • 网络安全专业毕业设计最新最全选题精华汇总-持续更新中

    前言 大家好 这里是海浪学长毕设专题 大四是整个大学期间最忙碌的时光 一边要忙着准备考研 考公 考教资或者实习为毕业后面临的升学就业做准备 一边要为毕业设计耗费大量精力 学长给大家整理了网络安全专业最新精选选题 如遇选题困难或选题有任何疑问
  • 将语雀文档迁移到飞书

    前言 我爬虫课程的文字版内容沉淀在语雀的知识库中 一开始感觉很不错 随着课程一直在卖 很快就超过了200人的限制 我已经是个人版中最高级的会员了 但语雀知识库的协作人数依旧限制在200人 即花钱无法解决问题 先说一下我的需求 我需要一个可以
  • 深度学习之实现图像数据增强

    深度学习之实现图像数据增强 前言 数据增强的意思就是让数据量增多 对于深度学习来说 大的数据量可以训练出更好的深度学习模型 在图像增强方面 我们常用的手段如下 旋转 翻转 缩放 平移 尺度变换 对比度变换 噪声扰动 颜色变换 1 使用ten
  • What the f*ck Python!(中文翻译版)

    What the f ck Python From https github com leisurelicht wtfpython cn 一些有趣且鲜为人知的 Python 特性 Python 是一个设计优美的解释型高级语言 它提供了很多能
  • SPFA 算法模板

    SPFA 代替 Dijkstra 计算最短路 题目 题目链接 题解 SPFA 一般时间复杂度为 O m O m O m 最坏情况下为 O
  • CNN人脸识别项目(dlib+opencv)

    CNN人脸识别 获取数据集 读取数据集 数据预处理 建立模型进行预训练 对图片进行人脸进行检测并进行可视化 总结 思路 一个CNN人脸识别项目首先必不可少的是数据集 获取的方式有网站数据库 PubFig Public Figures Fac