基于OpenCV和Keras的人脸识别系列手记:
项目完整代码参见Github仓库。
本篇手记是上面这一系列的第三篇。
之前已经准备好了训练模型需要用到的人脸图片,接下来的思路大致如下:
对数据进行简单的预处理;
用处理好的数据训练卷积神经网络并用测试数据评估模型性能;
如果模型准确率不够,考虑收集更多数据或用更复杂的网络继续迭代;
将模型预测结果作为接口给OpenCV捕获实时视频流的程序调用来识别人脸并进一步实现其他功能。
这篇手记讲解数据预处理部分。
前面我们是用OpenCV自带的人脸检测器提取的人脸,由于这个人脸检测器准确度有限,得到的人脸图片会有一些错误,我自己在检查的时候发现图片中有眼睛,门,手之类等等一些奇怪的图片也被保存了下来,如果这些图片不删掉就会导致训练出的模型有误差,所以在下一步处理数据之前就要手工检查数据,当然,这里的数据量不大(我一共收集了我和我女朋友的照片各一千张左右),所以手工检查数据的工作量也不大。
接着我们要用OpenCV统一图片尺寸大小以便输入到卷积神经网络中,我们在工作目录下建立一个load_face_dataset.py文件,定义一个resize_image函数来调整图片尺寸:
import os
import numpy as np
import cv2
IMAGE_SIZE = 64 # 指定图像大小
# 按指定图像大小调整尺寸
def resize_image(image, height = IMAGE_SIZE, width = IMAGE_SIZE):
top, bottom, left, right = (0,0,0,0)
# 获取图片尺寸
h, w, _ = image.shape
# 对于长宽不等的图片,找到最长的一边
longest_edge = max(h,w)
# 计算短边需要增加多少像素宽度才能与长边等长(相当于padding,长边的padding为0,短边才会有padding)
if h < longest_edge:
dh = longest_edge - h
top = dh // 2
bottom = dh - top
elif w < longest_edge:
dw = longest_edge - w
left = dw // 2
right = dw - left
else:
pass # pass是空语句,是为了保持程序结构的完整性。pass不做任何事情,一般用做占位语句。
# RGB颜色
BLACK = [0,0,0]
# 给图片增加padding,使图片长、宽相等
# top, bottom, left, right分别是各个边界的宽度,cv2.BORDER_CONSTANT是一种border type,表示用相同的颜色填充
constant = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value = BLACK)
# 调整图像大小并返回图像,目的是减