人脸识别在现在高科技的社会中,随处可见,作为一个初学者小白,根据老师上课的内容,完善了一个小型的人脸识别案例
import cv2
import os
import numpy as np
CASE_PATH="C:\\Users\Administrator\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml"
RAM_IMAGE_DIR ='./me/'
DATASET_DIR='./images/' #数据集
face_cascade=cv2.CascadeClassifier(CASE_PATH)
def save_faces(img,name,x,y,width,height):
image=img[y:y+height,x:x+width]
if img.size == 0:#对于这种情况就不要用imwriter
cv2.imwrite(name,image)
image_list=os.listdir(RAM_IMAGE_DIR)#列出文件夹下面所有的文件
count=166
for image_path in image_list:
fullpath=RAM_IMAGE_DIR+image_path
image=cv2.imread(fullpath)
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
faces=face_cascade.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=5,minSize=(5,5))
for(x,y,width,height)in faces:
save_faces(image,DATASET_DIR+image_path,x,y-30,width,height+30)
count+=1
前面的都是通用代码
对读取的图片进行处理
#为了方便后期卷积数据的输入,对切割出来的图片尺寸进行调整
def resize_without_deformation(image,size=(100,100)):
height,width,_=image.shape
longest_edge=max(height,width)
top,bottom,left,right=0,0,0,0
if height
#读取图片
def read_image(size=None):
data_x,data_y=[],[]
image_list=os.listdir(DATASET_DIR)#列出文件夹下面所有的文件
name=''
number=-1
for image_path in image_list:
fullpath=DATASET_DIR+image_path
myName=image_path.split('_')[0]
if myName != name:
name=myName
number+=1
try:
im=cv2.imread(fullpath)
except IOError as e:
print(e)
except:
print('Unknown Error!')
else:
if size is None:
size=(100,100)
im=resize_without_deformation(im,size)
data_x.append(np.asarray(im,dtype=np.int8))
data_y.append(number)
return data_x,data_y
接下来构建网络模型
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras import optimizers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
IMAGE_SIZE = 100
raw_images,raw_labels = read_image(size=(IMAGE_SIZE,IMAGE_SIZE))
raw_images,raw_labels = np.asarray(raw_images,dtype=np.float32),np.asarray(raw_labels,dtype = np.float32)
from keras.utils import np_utils
ont_hot_labels = np_utils.to_categorical(raw_labels)
from sklearn.model_selection import train_test_split
train_input,test_input,train_output,test_output= train_test_split(raw_images,ont_hot_labels,test_size=0.3)
train_input /= 255.0
test_input /= 255.0
模型输出
import tensorflow as tf
face_recongnition_model = tf.keras.models.Sequential()
face_recongnition_model.add(tf.keras.layers.Conv2D(32,(3,3),input_shape=(IMAGE_SIZE,IMAGE_SIZE,3),activation='relu',padding ='same'))
face_recongnition_model.add(tf.keras.layers.Conv2D(32,(3,3),activation='relu',padding ='same'))
face_recongnition_model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
face_recongnition_model.add(tf.keras.layers.Dropout(0.2))
face_recongnition_model.add(tf.keras.layers.Conv2D(64,(3,3),activation='relu',padding ='same'))
face_recongnition_model.add(tf.keras.layers.Conv2D(64,(3,3),activation='relu',padding ='same'))
face_recongnition_model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
face_recongnition_model.add(tf.keras.layers.Dropout(0.2))
face_recongnition_model.add(tf.keras.layers.Flatten())
face_recongnition_model.add(tf.keras.layers.Dense(512, activation = 'relu'))
face_recongnition_model.add(tf.keras.layers.Dropout(0.4))
face_recongnition_model.add(tf.keras.layers.Dense(len(ont_hot_labels[0]), activation = 'sigmoid'))
face_recongnition_model.summary()
learning_rate=0.01
decay=1e-6 #学习率衰减因子,用来随着迭代次数不断减小学习率,防止出现震荡
momentum=0.8 #引入冲量,可以在学习率较小的时候加速学习,又可以在学习率较大的时候减速
"""损失函数使用交叉熵,交叉熵函数随着输出核期望的差距越来越大,
曲线就会越来越陡峭,对权值的惩罚力度也会越来越大,其他的损失函数也是可以的"""
nesterov=True
#sgd=SGD(lr=learning_rate,decay=decay,momentum=momentum,nesterov=nesterov)
face_recongnition_model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=learning_rate,decay=decay,momentum=momentum,nesterov=nesterov),metrics=['acc'])
#开始训练,训练100次(epochs),每次训练分几个批次,每批(batch_size)20个,shuffle用来打乱样本顺序
batch_size=20 #每批训练数据量的大小
epochs=100
face_recongnition_model.fit(train_input,train_output,epochs=epochs,batch_size=batch_size,shuffle=True)
#训练完成后在测试集上评估结果并保存模型供以后加载使用
print(face_recongnition_model.evaluate(test_input,test_output,verbose=0))
MODEL_PATH='face_model.h5'
face_recongnition_model.save(MODEL_PATH)
from tensorflow import keras
#from keras.models import load_model
from tensorflow.keras.models import load_model
#加载卷积神经网络模型
face_recongnition_model=keras.Sequential()
MODEL_PATH='face_model.h5'
face_recognition_model=load_model(MODEL_PATH)
image=cv2.imread("test//Abhishek Bachan_20.jpg",1)
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#人脸检测:
faces=face_cascade.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=5,minSize=(30,30))
for(x,y,width,height) in faces:
img =image[y:y+height,x:x+width]
img =resize_without_deformation(img)
img=img.reshape((1,100,100,3))
img =np.asarray(img,dtype=np.float32)
img /=255.0
result =face_recognition_model.predict_classes(img)
cv2.rectangle(image,(x,y),(x+width,y+height),(0,255,0),2)
font=cv2.FONT_HERSHEY_SIMPLEX
if result[0]==8:
cv2.putText(image,'头像',(x,y-2),font,0.7,(0,255,0),2)
else:
cv2.putText(image,'No.%d' % result[0], (x, y-2), font, 0.7,(0, 255, 0),2)
cv2.imshow('',image)
cv2.waitKey(0)
最后识别的人脸能用彩色方框标注出来