从零搭建人脸识别系统(5)人脸识别系统

摸鱼了快两个月,把之前咕咕咕的补上。

这里就直接贴代码了(有空一定会补上说明的)。

train.py

from skimage import io,transform
import glob
import os
import tensorflow as tf
import numpy as np
import time

#图片路径
#path='D:/face_recognize/texture'
path='D:/faceRecognize/faces'
#定义预处理的图片大小为128*128,3通道
w=128
h=128
c=3

#最外层循环,建立独立训练的列表
for file_num in range(3):
#for file_num in range(1):
    print ('testing NO.%d dataset.......' % file_num)
    #读取图片方法,包含预处理
    def read_img(path):
        cate=[path+'/'+x for x in os.listdir(path) if os.path.isdir(path+'/'+x)]
        imgs=[]
        labs=[]
        for idx,folder in enumerate(cate):
            for im in glob.glob(folder+'/*.png'):
                print('加载图片:%s'%(im))
                img=io.imread(im)
                img=transform.resize(img,(w,h,c))
                imgs.append(img)
                labs.append(idx)
        return np.asarray(imgs,np.float32),np.asarray(labs,np.int32)
    #调用方法进行图片读取,并将数据与标签信息存入两个数组
    data,label=read_img(path)    
    num_example=data.shape[0]
    arr=np.arange(num_example)
    np.random.shuffle(arr)
    #数据数组
    data=data[arr]
    #label标签数组
    label=label[arr]
    
    ratio=0.8
    s=np.int(num_example*ratio)
    train_x=data[:s]#训练集数据
    train_y=label[:s]#训练集标签
    #以上是读取训练数据
    
    x_val=data[s:]#测试集数据
    y_val=label[s:]#测试集标签
    
    #给x,y_留出占位符,以便未来填充数据,x_img作为深度网络的输入,y_作为网络的标签输出
    x=tf.placeholder(tf.float32,shape=[None,w,h,c],name='x')
    y_=tf.placeholder(tf.int32,shape=[None,],name='y_')
    #dropout的参数
    keep_prob = tf.placeholder("float")
    
    #定义卷积网络
    def CNNlayer():
         #第一个卷积层(128——>64)
        conv1=tf.layers.conv2d(
            inputs=x,
            filters=32,#通道32
            kernel_size=[5, 5], #卷积核5*5
            padding="same",
            activation=tf.nn.relu,
            kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))#步长[1,1]
        pool1=tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)#最大池化,卷积核[2*2],步长为2
 
        #第二个卷积层(64->32)
        conv2=tf.layers.conv2d(
            inputs=pool1,
            filters=64,
            kernel_size=[5, 5],
            padding="same",
            activation=tf.nn.relu,
            kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
        pool2=tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
 
        #第三个卷积层(32->16)
        conv3=tf.layers.conv2d(
            inputs=pool2,
            filters=128,
            kernel_size=[3, 3],
            padding="same",
            activation=tf.nn.relu,
            kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
        pool3=tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2], strides=2)
 
        #第四个卷积层(16->8)
        conv4=tf.layers.conv2d(
            inputs=pool3,
            filters=128,
            kernel_size=[3, 3],
            padding="same",
            activation=tf.nn.relu,
            kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
        pool4=tf.layers.max_pooling2d(inputs=conv4, pool_size=[2, 2], strides=2)
 
        re1 = tf.reshape(pool4, [-1, 8 * 8 * 128])
 
        #全连接层
        dense1 = tf.layers.dense(inputs=re1, 
                          units=1024, 
                          activation=tf.nn.relu,
                          kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                          kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        dense2= tf.layers.dense(inputs=dense1, 
                          units=512, 
                          activation=tf.nn.relu,
                          kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                          kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        # 设置dropout,否则很容易过拟合
        dense3=tf.nn.dropout(dense2, keep_prob)
        
        logits= tf.layers.dense(inputs=dense3, 
                            units=60,#对应输出层个60标签
                            activation=None,
                            kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                            kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
        
        return logits
        #网络结构定义结束
    
    #调用网络结构函数
    logits=CNNlayer()
    #选用softmax作为最后激活函数
    loss=tf.losses.sparse_softmax_cross_entropy(labels=y_,logits=logits)
    # 设置误差代价以交叉熵的形式
    train_op=tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
    # 用adam的优化算法优化目标函数
    correct_prediction = tf.equal(tf.cast(tf.argmax(logits,1),tf.int32), y_)#比较标签数据和网络实际输出数据是否相等,判断准确率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))    
    acc= tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    
    #定义一个函数,按批次取数据
    def minibatches(inputs=None, targets=None, batch_size=None, shuffle=False):
        assert len(inputs) == len(targets)
        if shuffle:
            indices = np.arange(len(inputs))
            np.random.shuffle(indices)
        for start_idx in range(0, len(inputs) - batch_size + 1, batch_size):
             if shuffle:
                 excerpt = indices[start_idx:start_idx + batch_size]
             else:
                 excerpt = slice(start_idx, start_idx + batch_size)
             yield inputs[excerpt], targets[excerpt]
    
    #保存训练好的模型参数
    saver=tf.train.Saver(max_to_keep=3)
    #min_loss为训练终止标准,也可以直接训练迭代完整个n_epoch
    min_loss=1
    
    #定义算子
    sess=tf.InteractiveSession()  
    sess.run(tf.global_variables_initializer())
    #开始训练
    #迭代n_epoch次,每次抽出的样本数目为batch_size
    n_epoch=3000
    batch_size=64
    for epoch in range(n_epoch):
        train_loss, train_acc, n_batch = 0, 0, 0
        for x_train_a, y_train_a in minibatches(train_x, train_y, batch_size, shuffle=True):
            _,err,ac=sess.run([train_op,loss,acc], feed_dict={x: x_train_a, y_: y_train_a,keep_prob: 0.6})
             # 设置dropout的参数为0.6,
        if train_loss<min_loss:
            min_loss=train_loss
            #print("模型误差为"%min_loss)
        val_loss, val_acc, n_batch = 0, 0, 0
        for x_val_a, y_val_a in minibatches(x_val, y_val, batch_size, shuffle=False):
            err, ac = sess.run([loss,acc], feed_dict={x: x_val_a, y_: y_val_a,keep_prob: 1.0})
            val_loss += err; val_acc += ac; n_batch += 1
    #终止训练的评判标准,也可以训练整个n_epoch,此处没有使用
    #if min_loss<1e-6  
    saver.save(sess,'ckpt1/faces.ckpt',global_step=epoch+1)                
  
    print("第%d次训练完成"% file_num)
    print ("第%d次测试的准确率"% file_num+"test accuracy: %g"%(val_acc/n_batch))
    #这一句结果和上面的相同,都是取平均  
    #print ("第%d次测试的准确率"% file_num+"test accuracy: %g"%ac.eval(feed_dict={x: x_val_a, y_: y_val_a, keep_prob: 1.0}))

sess.close()

test.py

from skimage import io,transform
import glob
import os
import tensorflow as tf
import numpy as np
import time
import cv2 
import dlib
import sys
 

 
ID=(1511277,1511278,1511279,1511282,1511283,1511286,1511287,1511289,
    1511290,1511291,1511292,1511295,1511296,1511298,1511300,1511301,
    1511302,1511303,1511304,1511305,1511306,1511307,1511308,1511310,
    1511311,1511312,1511313,1511315,1511317,1511318,1511319,1511323,
    1511325,1511328,1511329,1511330,1511332,1511333,1511334,1511337,
    1511339,1511340,1511341,1511342,1511343,1511344,1511345,1511347,
    1511349,1511350,1511351,1511352,1511353,1511355,1511357,1511358,
    1511360,1511361,1511363,1511365)
 
 
w=128
h=128
c=3
 
x=tf.placeholder(tf.float32,shape=[None,w,h,c],name='x')
y_=tf.placeholder(tf.int32,shape=[None,],name='y_')
 
def CNNlayer():
    #第一个卷积层(128——>64)
    conv1=tf.layers.conv2d(
          inputs=x,
          filters=32,
          kernel_size=[5, 5],
          padding="same",
          activation=tf.nn.relu,
          kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
    pool1=tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
 
    #第二个卷积层(64->32)
    conv2=tf.layers.conv2d(
          inputs=pool1,
          filters=64,
          kernel_size=[5, 5],
          padding="same",
          activation=tf.nn.relu,
          kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
    pool2=tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
 
    #第三个卷积层(32->16)
    conv3=tf.layers.conv2d(
          inputs=pool2,
          filters=128,
          kernel_size=[3, 3],
          padding="same",
          activation=tf.nn.relu,
          kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
    pool3=tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2], strides=2)
 
    #第四个卷积层(16->8)
    conv4=tf.layers.conv2d(
          inputs=pool3,
          filters=128,
          kernel_size=[3, 3],
          padding="same",
          activation=tf.nn.relu,
          kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
    pool4=tf.layers.max_pooling2d(inputs=conv4, pool_size=[2, 2], strides=2)
 
    re1 = tf.reshape(pool4, [-1, 8 * 8 * 128])
 
    #全连接层
    dense1 = tf.layers.dense(inputs=re1, 
                          units=1024, 
                          activation=tf.nn.relu,
                          kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                          kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
    dense2= tf.layers.dense(inputs=dense1, 
                          units=512, 
                          activation=tf.nn.relu,
                          kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                          kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
    logits= tf.layers.dense(inputs=dense2, 
                            units=60,
                            activation=None,
                            kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                            kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
    return logits

logits=CNNlayer()
predict = tf.argmax(logits, 1)
detector = dlib.get_frontal_face_detector() 
saver = tf.train.Saver()
sess = tf.Session()
saver.restore(sess, 'ckpt1/faces.ckpt-9')
 
 
user=input("图片(G)还是摄像头(V):")
if user=="G":
    path=input("图片路径名是:")
    img = cv2.imread(path)
    dets = detector(img, 1) 
    #print("Number of faces detected: {}".format(len(dets)))
    for index, face in enumerate(dets):
        print('face {}; left {}; top {}; right {}; bottom {}'.format(index, face.left(), face.top(), face.right(), face.bottom()))
        left = face.left()
        top = face.top()
        right = face.right()
        bottom = face.bottom()
        cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0), 3)
        io.imsave('temp.png', img)
        img1=io.imread('temp.png') 
        img1=transform.resize(img1,(w,h,c))
        cv2.imshow('image',img1)
        
        img1 = img[top:bottom,left:right] 
        img1=transform.resize(img1,(w,h,c))
        # cv2.imshow('image1',img)
        res=sess.run(predict, feed_dict={x:[img1]})
        print(ID[res[0]])
    if len(dets)==0:
        img=transform.resize(img,(w,h,c))
        res=sess.run(predict, feed_dict={x:[img]})
        print(ID[res[0]])
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    cv2.waitKey(0)
    cv2.destroyAllWindows()
else:
    cap = cv2.VideoCapture(0)
 
    while True:
        ret, frame = cap.read()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow('frame', frame)
 
        if cv2.waitKey(1) & 0xFF == ord('s'):
            cv2.imwrite('image/now.png', frame)
 
            img = cv2.imread("image/now.png")
            dets = detector(img, 1) 
            print("Number of faces detected: {}".format(len(dets))) 
            for index, face in enumerate(dets):
                print('face {}; left {}; top {}; right {}; bottom {}'.format(index, 
                    face.left(), face.top(), face.right(), face.bottom()))
                left = face.left()
                top = face.top()
                right = face.right()
                bottom = face.bottom()
                img = img[top:bottom,left:right]
 
            img=transform.resize(img,(w,h,c))
            res=sess.run(predict, feed_dict={x:[img]})
            print(ID[res[0]])
 
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
 
    cap.release()
    cv2.destroyAllWindows()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值