作者:兜兜岁月真伟大 | 来源:互联网 | 2023-09-25 16:47
前言最近自己尝试了python+opencv实现简单的人脸识别,接下来我将一步步讲解我实现其功能的详细步骤,有不对的地方请指正具体的功能是:识别图片或者视频片段中的人脸,打印出识别
前言
最近自己尝试了python+opencv实现简单的人脸识别,接下来我将一步步讲解我实现其功能的详细步骤,有不对的地方请指正
具体的功能是:识别图片或者视频片段中的人脸,打印出识别的信息
模块
这里我将罗列我们需要使用的模块
- opencv(cv2) : 这是我们实现人脸识别的主要模块
- os :文件操作
- xlrd :操作excel(我将一部分信息放在excel中)
- pillow :图像处理标准库
- numpy :数组运算 (通常我们可以将彩色图片看作三维数组,黑白图片看作二维数组)
功能实现
1.目录介绍
这是我创建的文件目录,下面我将依次介绍相应信息(该文件夹是按照自己习惯建立,大家只需要了解具体用处即可)
- image: 存放照片的总文件夹
- imge/colours: 存放用来训练模型的照片
- image/need_recognize: 存放需要识别的照片
- image/video: 存放需要识别的视频
- info/faceInfo.xls: 存放照片训练模型照片的相应信息
- train/train.yml: 训练好的模型文件
- haarcascade_frontalface_default.xml: opencv人脸识别文件,需自行下载
- recognize.py: 实现人脸识别功能的文件
- train.py: 实现模型训练的文件
2.训练模块
模型训练最终会生成train.yml文件,在train.py中,我定义了两个函数来完成改功能,我将会在代码注释部分详细讲解其作用。
#train.py => getImageAndLabels(images_path)
def getImageAndLabels(images_path): # 传入模型训练的照片路径
faces = []
ids = []
face_detector = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
# 引用人脸识别模块 (这个模块来自opencv开源人脸模块)
images = [os.path.join(images_path, title) for title in os.listdir(images_path)]
# 将路径下照片依次放入images列表
for image in images:
gray_image = Image.open(image).convert('L') # 灰度照片
image_numpy = np.array(gray_image, 'uint8') # 将照片转化为数组
face_site = face_detector.detectMultiScale(image_numpy) # 检测人脸并存入
id = os.path.split(image)[1].split('.')[0]
# 将每张照片的id记录
if not len(face_site):
print(image, '无法识别')
else:
for x, y, w, h in face_site:
faces.append(image_numpy[y:y + h, x:x + w])
ids.append(int(id))
return faces, ids # 返回所有照片的人脸数据和id
#train.py => train_data(face_image_path)
def train_data(face_image_path): # 传入模型训练的照片路径
faces, ids = getImageAndLabels(face_image_path) # 获取所有照片人脸数据和id
recognizer = face.LBPHFaceRecognizer_create() # 引入训练模型的函数
recognizer.train(faces, np.array(ids)) # 训练模型
recognizer.write('trainer/trainer.yml') # 创建训练模型的文件或重新写入
3.识别模块
在识别模块中,对于照片的人脸识别和视频的人脸识别,其实现方式是相同的,故我将视频的每一帧作为照片传入函数进行识别,达到复用函数的目的,该模块共定义了四个函数。
#recognize.py => read_info(id_info)
def read_info(id_info): # 传入需要识别出的人脸id
excel = xlrd.open_workbook(excel_path)
sheet = excel.sheet_by_index(0)
name = sheet.row_values(id_info + 1)[1] # 查找传入id照片的信息
return name
#recognize.py => face_recognize(image, isVideo)
def face_recognize(image, isVideo): # 传入需要识别的照片以及该照片是否属于视频的一帧
recognizer.read('trainer/trainer.yml') # 读取训练模型
gray_img = cv.cvtColor(image, cv.COLOR_BGR2GRAY) # 将图片灰度转换
faces = face_detector.detectMultiScale(gray_img) # 检测图片中人脸部分
for x, y, w, h in faces:
cv.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 在原图中圈出人脸
id, cOnfidence= recognizer.predict(gray_img[y:y + h, x:x + w])
# 返回id、置信度
name = read_info(id)
if confidence <100:
print(id, name)
else:
print('识别度较低')
name = '识别度较低'
image = cv.resize(image, (300, 400)) # 限定展示照片的大小
cv.imshow('result', image)
if not isVideo:
cv.waitKey(0)
#recognize.py => image_face_recognize(recognize_image_path)
def image_face_recognize(recognize_image_path): # 传入需要识别的照片都总路径
lists = [os.path.join(recognize_image_path, title) for title in os.listdir(recognize_image_path)]
# 将路径下所有照片的具体路径存入lists列表
for item in lists:
image = cv.imread(item) # 读取图片
face_recognize(image, False) # 调用识别函数
cv.destroyAllWindows()
#recognize.py => video_face_recognize(video_path)
def video_face_recognize(video_path): # 传入视频路径
lists = [os.path.join(video_path, title) for title in os.listdir(video_path)]
print(lists)
for item in lists:
print(item)
capture = cv.VideoCapture(item) # 打开视频
while True:
flag, frame = capture.read() # 读取视频每一帧
if not flag:
break
face_recognize(frame, True) # 传入该帧图片
if ord('q') == cv.waitKey(10):
break
总结
目前人脸识别我只采用 'haarcascade_frontalface_default.xml' 模块,如果需要更高的精度可以结合更多的模块一起进行处理和识别。同时,增加模型训练中一组照片的数量也能在一定程度上提高人脸识别精度。