首页 > 编程知识 正文

dlib 人脸识别,dlib人脸识别准确率

时间:2023-05-05 23:36:43 阅读:281649 作者:1519

上一篇博客是opencv来读取视频或者照片,但是使用opencv有一个弊端,就是在centos服务器上,opencv不能读取视频,照片是可以的,如果想读取视频,需要大量的安装包来安装,很不方便,这里就使用av来代替opencv来读取视频,识别还是交给dlib来实现:

import datetimeimport redisfrom skimage import ioimport numpy as npimport cv2import dlibimport avfrom PIL import Image# 要读取人脸图像文件的路径 / Path of cropped facespath_images_from_camera = "/home/image_recognition/image/"# Dlib 正向人脸检测器 / Use frontal face detector of Dlibdetector = dlib.get_frontal_face_detector()# Dlib 人脸 landmark 特征点检测器 / Get face landmarkspredictor = dlib.shape_predictor('/home/image_recognition/code/shape_predictor_68_face_landmarks.dat')# Dlib Resnet 人脸识别模型,提取 128D 的特征矢量 / Use Dlib resnet50 model to get 128D face descriptorface_reco_model = dlib.face_recognition_model_v1("/home/image_recognition/code/dlib_face_recognition_resnet_model_v1.dat")class ReadVideo: def __init__(self, path): self.container = av.open(path) self.video = self.container.streams.video[0] self.size = self.video.width, self.video.height self.frames = self.video.frames self.duration = self.container.duration / 1000 self.rate = self.video.rate self.bit_rate = self.video.bit_rate def read(self): for packet in self.container.demux(self.video): for frame in packet.decode(): yield frame# 连接数据库redis,存放数据def sava_redis_info(key, value): if not isinstance(value, list): print('数据类型错误') return r = redis.Redis(host='47.xxx.xxx.61', 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(path_img, 1) if len(faces) != 0: shape = predictor(path_img, faces[0]) face_descriptor = face_reco_model.compute_face_descriptor(path_img, 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() r_video = ReadVideo(video_path) image_num = 0 image_num_no = 1 try: for frame in r_video.read(): img = frame.to_image() # 检测人脸 faces = detector(np.array(img), 0) # 如果检测到有人脸 if len(faces) != 0: vector_list = [] for i in range(len(faces)): shape = predictor(np.array(img), faces[i]) vector_list.append(face_reco_model.compute_face_descriptor(np.array(img), 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 main2(identification, path, type=2): # 1. 获取要识别图片对路径 # path_images_from_camera = "/home/image_recognition/image/" # image_path = path_images_from_camera + path # 2. 获取要识别图片对128d特征 face_descriptor = return_128d_features(path) if not face_descriptor: return False # 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))) return True else: # print("不是同一个人,相似度为{}".format(1-float(new_res_dist))) return False# res = main2("13781972862", "img_face_2.jpg", type=2)# print(res)video_dispose("/home/image_recognition/code/2.mp4", "13781972862")

使用av和opencv读取视频都是可以的,看个人选择,如果dlib不能满足你的需求,那么我使用srcfd封装了人脸识别,速度比dlib提高了8倍,大家可以下载使用:
Dlib 人脸 landmark 特征点检测器和
Dlib Resnet 人脸识别模型,提取 128D 的特征矢量的库可以使用云盘下载:
链接: https://pan.baidu.com/s/1nQ6BTiWsOtlvB_Qoh3bqzA
提取码: 69e1

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。