使用opencv和dlib来进行人脸识别
·
人脸识别流程不在介绍,直接上代码,改下识别包和图片路径即可运行识别:
import cv2
import dlib
from skimage import io
import numpy as np
import redis
import datetime
# 要读取人脸图像文件的路径 / Path of cropped faces
path_images_from_camera = "/Users/a123456/software/opencvtxt/data/data_faces_from_camera/person_1/"
# Dlib 正向人脸检测器 / Use frontal face detector of Dlib
detector = dlib.get_frontal_face_detector()
# Dlib 人脸 landmark 特征点检测器 / Get face landmarks
predictor = dlib.shape_predictor('/Users/a123456/software/opencvtxt/Dlib/data/data_dlib/shape_predictor_68_face_landmarks.dat')
# Dlib Resnet 人脸识别模型,提取 128D 的特征矢量 / Use Dlib resnet50 model to get 128D face descriptor
face_reco_model = dlib.face_recognition_model_v1("/Users/a123456/software/opencvtxt/Dlib/data/data_dlib/dlib_face_recognition_resnet_model_v1.dat")
# 连接数据库redis,存放数据
def sava_redis_info(key, value):
if not isinstance(value, list):
print('数据类型错误')
return
r = redis.Redis(host='47.xxx.xx.xxx', port=6379, password='', db=1, decode_responses=True)
# 对values进行处理
end_info = str(value)[1:len(str(value))-1].replace(" ", "")
r.lpush(key, end_info)
r.expire(key, 3600)
print("保存成功!")
# 连接数据库redis, 取出数据
def get_redis_info(key):
r = redis.Redis(host='47.xxx.xxx.xxx', port=6379, password='', db=1, decode_responses=True)
index_res = r.llen(key)
if index_res == 0:
print("数据不存在")
return 0
redis_list = r.lrange(key, 0, index_res)
new_list = []
for i in redis_list:
new_list.append(list(i.split(",")))
return new_list
# 计算图片到128d特征
def return_128d_features(path_img):
img_rd = io.imread(path_img)
# 判断图片中是否有人脸
faces = detector(img_rd, 1)
if len(faces) != 0:
shape = predictor(img_rd, faces[0])
face_descriptor = face_reco_model.compute_face_descriptor(img_rd, shape)
else:
print("未检测到人脸")
return 0
return face_descriptor
# 计算两个128D向量间的欧式距离
def return_euclidean_distance(feature_1, feature_2):
feature_1 = np.array(feature_1)
feature_2 = np.array(feature_2)
dist = np.sqrt(np.sum(np.square(feature_1 - feature_2)))
return dist
# 将视频变为一张张图片
def video_save_image(frame, save_path, image_name, frame_count):
resize_frame = cv2.resize(frame, (576, 1024), interpolation=cv2.INTER_AREA)
cv2.imwrite(save_path + "{}-{}.jpg".format(image_name, frame_count), resize_frame)
# 对视频进行处理
def video_dispose(video_path, key):
"""
:param video_path: 视频路径
:return:
3 帧宽
4 帧高
"""
time1 = datetime.datetime.now()
image = cv2.VideoCapture(video_path)
# image.set(4, 480) # 640x480
# image.set(3, 640) # 640x480
image_num = 0
image_num_no = 1
try:
# 只要视频不停止则一直捕获
while (image.isOpened()):
# 逐帧捕获
is_success, frame = image.read()
# 检测人脸
faces = detector(frame, 0)
# 按下q键则退出
kk = cv2.waitKey(1)
if kk == ord('q'):
break
# 如果检测到有人脸
if len(faces) != 0:
vector_list = []
for i in range(len(faces)):
shape = predictor(frame, faces[i])
vector_list.append(face_reco_model.compute_face_descriptor(frame, shape))
# 取出数据
res_list = get_redis_info(key)
redis_list_len = len(res_list)
res_dist = 0
# 计算欧式距离
for i in res_list:
s_list = []
for m in i:
s_list.append(float(m))
res_dist = res_dist + return_euclidean_distance(s_list, list(vector_list))
new_res_dist = res_dist / redis_list_len
if new_res_dist <= 0.4:
image_num += 1
# 保存图片
# video_save_image(frame, path_images_from_camera, "video", image_num)
print("是同一个人,相似度为{}".format(1-float(new_res_dist)))
else:
image_num_no += 1
print("不是同一个人,相似度为{}".format(1 - float(new_res_dist)))
except Exception as e:
time2 = datetime.datetime.now()
print("视频结束!一共识别图片{}张!未识别图片{}张,耗时{}".format(image_num, image_num_no, time2-time1))
# 图片识别运行入口
def main(identification, path, type=2):
# 1. 获取要识别图片对路径
# path_images_from_camera = "/Users/a123456/software/opencvtxt/data/data_faces_from_camera/person_1/"
# image_path = path_images_from_camera + path
image_path = path
# 2. 获取要识别图片对128d特征
face_descriptor = return_128d_features(image_path)
if not face_descriptor:
return
# 2.1 如果是保存特征值
if type == 1:
sava_redis_info(identification, list(face_descriptor))
return
# 2.2 获取数据库中存储的128d特征
res_128d = get_redis_info(identification)
redis_list_len = len(res_128d)
res_dist = 0
if not res_128d:
return
for i in res_128d:
s_list = []
for m in i:
s_list.append(float(m))
# 3. 计算两个128D向量间的欧式距离、
res_dist = res_dist + return_euclidean_distance(list(face_descriptor), s_list)
new_res_dist = res_dist / redis_list_len
# 4. 判断是否是同一个人
if new_res_dist <= 0.40:
print("是同一个人,相似度为{}".format(1-float(new_res_dist)))
else:
print("不是同一个人,相似度为{}".format(1-float(new_res_dist)))
time1 = datetime.datetime.now()
main("13781972862", "img-1.jpg", type=2)
time2 = datetime.datetime.now()
print(time2-time1)
# video_dispose("/Users/a123456/software/opencvtxt/data/data_faces_from_camera/person_1/1633745580459094.mp4", "13781972862")
Dlib 人脸 landmark 特征点检测器和
Dlib Resnet 人脸识别模型,提取 128D 的特征矢量的库可以使用云盘下载:
链接: https://pan.baidu.com/s/1nQ6BTiWsOtlvB_Qoh3bqzA
提取码: 69e1
这主要是使用dlib来实现的,效率不高,但是还可以!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)