准备阶段

  1. 准备三个目录 一个放 识别好的人脸标本,一个放需要识别的照片,一个放识别后的结果

比如:

python利用opencv实现本地图片的识别与结果存储_opencv

  1. 需要安装opencv包、dlib包,以及下载人脸数据,参照:​​python利用opencv读取摄像头数据​
  2. 另外还需要安装人脸比对的包

实现步骤

  1. 读取识别好的人脸标本,并解析
  2. 读取需要检测的人脸图片,解析并与标本比对
  3. 比对成功则绘制绿框,标出姓名

代码实现

# This is a sample Python script.
import os.path

# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
import cv2 as cv
import dlib
import numpy as np
import face_recognition

# 加载人脸检测器和关键点检测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

# 已知人脸存储路径
known_face_path = 'faces/gugu/'
# 需要检测的人脸存储路径
unknown_face_path = 'faces/gys/'
# 记录结果
record_face_path = 'faces/record/'


def recognize_image():
# 读取已知人脸,并解析
known_face_encodings = []
known_face_names = []
print('开始加载已知人脸数据...')
for root, dirs, files in os.walk(known_face_path):
total_process = len(files)
process = 0
for f, file in enumerate(files):
img = face_recognition.load_image_file(known_face_path + file)
face_encodings = face_recognition.face_encodings(img, model='cnn')
if len(face_encodings) > 0:
known_face_encodings.append(face_encodings[0])
known_face_names.append(file[0:file.index('.')])
process += 1
print('----> 已加载' + str(process / total_process * 100 // 1) + '%')
print('数据加载完成!')

# 识别人脸数据
if not os.path.exists(record_face_path):
os.makedirs(record_face_path)

for root, dirs, files in os.walk(unknown_face_path):
total_process = len(files)
process = 0
for f, file in enumerate(files):
cv_img = cv.imdecode(np.fromfile(unknown_face_path + file, dtype=np.uint8), cv.IMREAD_COLOR)

# img = face_recognition.load_image_file(unknown_face_path + file)
img = cv.cvtColor(cv_img, cv.COLOR_BGR2RGB)
locations = face_recognition.face_locations(img)
face_encodings = face_recognition.face_encodings(img, locations, model='cnn')
for (top, right, bottom, left), face_encoding in zip(locations, face_encodings):
matches = face_recognition.compare_faces(known_face_encodings, face_encoding, .5)
if True in matches:
index = matches.index(True)
name = known_face_names[index]
# 绘制矩形框
cv.rectangle(cv_img, (left, top, right - left, bottom - top), (0, 255, 0), 2)
cv.putText(cv_img, name, (left + 10, bottom - 10), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv.imencode('.jpg', cv_img, [cv.IMWRITE_JPEG_QUALITY, 100])[1].tofile(record_face_path + '副本_' + file)

process += 1
print('----> 已识别' + str(process / total_process * 100 // 1) + '%')


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
print_hi('PyCharm')
recognize_image()

已知问题:如果姓名是中文,绘制到图片上,会以问号的形式打印


注意:matches = face_recognition.compare_faces(known_face_encodings, face_encoding, .5) 中需要调整比较距离tolerance的值,以达到需要的效果


输出结果

python利用opencv实现本地图片的识别与结果存储_opencv_02