糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 【Pytorch深度学习50篇】·······第二篇:【人脸识别】(2)

【Pytorch深度学习50篇】·······第二篇:【人脸识别】(2)

时间:2020-02-26 15:50:12

相关推荐

【Pytorch深度学习50篇】·······第二篇:【人脸识别】(2)

重磅!!!!代码来了~~~~

连续更新的第二篇,这边是上一篇的续集,在这里我已经假设你已经完成了,上一篇的环境安装的工作,今天我们就来手撕代码,注入灵魂。今天正式就进入代码篇了。我局的我已经把代码掰开揉碎了来讲了,大家肯定看的明白。

所以先不啰嗦,直接先把代码提贴出来,一共两个脚本,一个是收集人脸特征的代码,一个是判断人脸相似度的代码。在这之前还是先贴出一张检测后的图片,目的是为了吸引观众朋友们。

1.收集人脸特征的代码

import cv2import dlibimport osimport numpy as npdef drawrec_drawdot(shape,image):landmarks = shape.parts()landmarks = np.matrix([[p.x, p.y] for p in landmarks])#画图for idx, point in enumerate(landmarks):# 68点的坐标pos = (point[0, 0], point[0, 1])# 利用cv2.circle给每个特征点画一个圈,共68个cv2.circle(image, pos, 2, color=(0, 255, 0), thickness=3)# 利用cv2.putText输出1-68font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(image, str(idx + 1), None, font, 0.8, (0, 0, 255), 1, cv2.LINE_AA)return imageif __name__ == '__main__':#定义图片文件夹路径folder_path = r'D:\DATAS\manhua\manhua_tou'upper_path = '\\'.join(folder_path.split('\\')[:-1])numpy_data_save_folder = os.path.join(upper_path,'TENSOR')output_image_folder = os.path.join(upper_path,'OUTPUT')if not os.path.exists(numpy_data_save_folder):os.makedirs(numpy_data_save_folder)if not os.path.exists(output_image_folder):os.makedirs(output_image_folder)#定义定位人脸的定位器detector = dlib.get_frontal_face_detector()#定义检测人脸特征点的检测器predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")feature_value_detctor = dlib.face_recognition_model_v1('./dlib_face_recognition_resnet_model_v1.dat')for i in os.listdir(folder_path):for j in os.listdir(os.path.join(folder_path, i)):# 图片路径image_path = os.path.join(folder_path, i, j)image = cv2.imread(image_path)# 获取人脸坐标locations = detector(image)if len(locations) != 0:for location in locations:#获取64个特征点shape_64 = predictor(image,location)#将64个特征点转变成128维的向量face_descriptor = pute_face_descriptor(image, shape_64)value_128 = np.array(face_descriptor)# print(value_128)np.save(numpy_data_save_folder + '/' + image_path.split('\\')[-1].split('.')[0],value_128)# 画人脸位置和64个特征点draw_image = drawrec_drawdot(shape_64,image)# 保存图像cv2.imwrite(os.path.join(output_image_folder,j),draw_image)

从主函数看起:

1.1定义图片文件和创建两个必要的文件夹

if __name__ == '__main__':#定义图片文件夹路径folder_path = r'D:\DATAS\manhua\manhua_tou'upper_path = '\\'.join(folder_path.split('\\')[:-1])numpy_data_save_folder = os.path.join(upper_path,'TENSOR')output_image_folder = os.path.join(upper_path,'OUTPUT')if not os.path.exists(numpy_data_save_folder):os.makedirs(numpy_data_save_folder)if not os.path.exists(output_image_folder):os.makedirs(output_image_folder)

首先我定义了一个文件夹路径folder_path,它是图片所在的文件夹,这个文件下,是这样的

以人的名称直接来命名,因为我的数据集只有pangpang和shouhsou,所以只有两个子文件夹,还是给大家看看里面吧,哈哈,别羡慕,题外话了,哈哈。

里面的图片最好也以人的名称命名,方便以后操作

好了,好了,说回代码

然后我又定义了一个numpy_data_save_folder 和 output_image_folder,然后创建了这个两个文件夹,以便后面程序往这两个文件中生成文件。

1.2定义人脸定位器和检测器

#定义定位人脸的定位器detector = dlib.get_frontal_face_detector()#定义检测人脸特征点的检测器predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")feature_value_detctor = dlib.face_recognition_model_v1('./dlib_face_recognition_resnet_model_v1.dat')

这个你就看到了,昨天我的那篇文章让你配置环境的重要性了吧,我在这里再提供一下,下载路径

链接:/s/1PReHKPiG0ZSCXTiy75TtCQ

提取码:dbr5

够意思了吧。

简单说一下,detector是用于定位人脸位置的,predictor是用于检测人脸的64个特征点的,feature_value_detctors是用于将64个特征点转变成128维向量的工具

1.3遍历读图,进行检测,存储人脸128维特征向量和检测图

for i in os.listdir(folder_path):for j in os.listdir(os.path.join(folder_path, i)):# 图片路径image_path = os.path.join(folder_path, i, j)image = cv2.imread(image_path)# 获取人脸坐标locations = detector(image)if len(locations) != 0:for location in locations:#获取64个特征点shape_64 = predictor(image,location)#将64个特征点转变成128维的向量face_descriptor = pute_face_descriptor(image, shape_64)value_128 = np.array(face_descriptor)# print(value_128)np.save(numpy_data_save_folder + '/' + image_path.split('\\')[-1].split('.')[0],value_128)# 画人脸位置和64个特征点draw_image = drawrec_drawdot(shape_64,image)# 保存图像cv2.imwrite(os.path.join(output_image_folder,j),draw_image)

先利用os库来找到图片的路径,然后读图,这两步都没问题吧,默认没问题

locations = detector(image)

这一行代码,就是在定位图片中人脸的位置了,图片上有几个人,会定位到几个,所以你看我命名的时候用用的locations,有一个‘s’,表示多个,哈哈,严谨!

shape_64 = predictor(image,location)

这一行代码就是提取人脸的64个特征点了,文章最开头的那张美女图上的那些绿点就是画上去的特征点,不是麻子,应该没问题吧

face_descriptor = pute_face_descriptor(image, shape_64)

这一行代码就是把64个特征点变成128维的向量,我们来看看这个128维向量长什么样子吧

这绝对是128个数,不信你数一数。

np.save(numpy_data_save_folder + '/' + image_path.split('\\')[-1].split('.')[0],value_128)# 画人脸位置和64个特征点draw_image = drawrec_drawdot(shape_64,image)# 保存图像cv2.imwrite(os.path.join(output_image_folder,j),draw_image)

这个时候1.1里面个建立的两个文件夹就派上用场了,他们一个用来存储128维度的数据,一个用来保存生成后的图,运行脚本完成后,如下

看看里面

这个npy文件存储的numpy格式的数据

好了,收集人脸特征到这里就结束了,大家一起来试一试吧。

2.判断人脸相似度

老规矩,先上代码

import cv2import dlibimport osimport numpy as npdef load_tensor(tensor_folder):feature_list = [] # 用于存放人物128维特征值列表class_name = [] # 用于存放类别信息for i in os.listdir(tensor_folder):tensor_path = os.path.join(tensor_folder,i)tensor = np.load(tensor_path)feature_list.append(tensor)class_name.append(tensor_path.split('\\')[-1].split('.')[0])return feature_list,class_nameif __name__ == '__main__':#--------------init--------------------------detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")feature_value_detctor = dlib.face_recognition_model_v1('./dlib_face_recognition_resnet_model_v1.dat')#-------------加载信息------------------------tensor_folder = r'D:\DATAS\manhua\TENSOR'feature_list, class_name = load_tensor(tensor_folder)#-------------开始测试------------------------test_image_path = r'D:\DATAS\test\pangpang (28).jpg'test_image = cv2.imread(test_image_path)locations = detector(test_image)dist = []for k, loc in enumerate(locations):shape = predictor(test_image, loc)face_descriptor = pute_face_descriptor(test_image, shape)d_test = np.array(face_descriptor)for i in feature_list:#计算距离distance = np.linalg.norm(i-d_test)dist.append(distance)distance_dict = dict(zip(class_name, dist))distance_sorted = sorted(distance_dict.items(), key=lambda x:x[1])print ("识别到的人物最有可能是: ",distance_sorted[0][0].split('(')[0])font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(test_image, distance_sorted[0][0].split('(')[0], (int(test_image.shape[0]//2)-50,test_image.shape[1]-50), font, 0.8, (0, 0, 255), 3, cv2.LINE_AA)cv2.imshow('test_image', test_image)cv2.waitKey()

2.1 定义人脸定位器和检测器和加载刚刚提取的人脸特征数据

if __name__ == '__main__':#--------------init--------------------------detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")feature_value_detctor = dlib.face_recognition_model_v1('./dlib_face_recognition_resnet_model_v1.dat')#-------------加载信息------------------------tensor_folder = r'D:\DATAS\manhua\TENSOR'feature_list, class_name = load_tensor(tensor_folder)

我们来看看load_tensor这个函数

def load_tensor(tensor_folder):feature_list = [] # 用于存放人物128维特征值列表class_name = [] # 用于存放类别信息for i in os.listdir(tensor_folder):tensor_path = os.path.join(tensor_folder,i)tensor = np.load(tensor_path)feature_list.append(tensor)class_name.append(tensor_path.split('\\')[-1].split('.')[0])return feature_list,class_name

传入的参数是tensor_folder,这个参数就是刚刚第一个程序里创建的那个TENSOR文件夹的路径

最后返回值是,所有的128维特征的列表和特征对应的类别,也是pangpang或者shoushou。

2.2开始检测求欧氏距离

test_image_path = r'D:\DATAS\test\pangpang (28).jpg'test_image = cv2.imread(test_image_path)locations = detector(test_image)dist = []for k, loc in enumerate(locations):shape = predictor(test_image, loc)face_descriptor = pute_face_descriptor(test_image, shape)d_test = np.array(face_descriptor)for i in feature_list:#计算距离distance = np.linalg.norm(i-d_test)dist.append(distance)

test_image_path是你要用来测试的图片的路径,然后就是先得到测试图的128维度的特征向量,然后计算这个向量和你刚刚第一个程序里面保存的那些特征向量的欧式距离,np.linalg.norm这个函数就是用来求欧式距离的,i-d_test,就是两个向量之间的差值,np.linalg.norm就是实现

这么说吧,v1是一个128维度的向量,v2是一个128维度的向量,要求得他们的欧氏距离

此时,这里面的x1就相当于v1[0]-v2[0],这么说清晰了吧,你要是还是想不明白,你就想想初中数学,求直角坐标系中的任意两点p1,p2的距离怎么求,p1点坐标(x1,y1),拍p2点坐标(x2,y2)

这样说应该清楚了吧,这样就求到了,这个测试图的128维度特征向量和之前每个128维特征向量的距离了,保存成了一个了列表dist

2.3开始求最小的距离

距离也就意味着最为相似,这样我们就认为他们是同一个人。

distance_dict = dict(zip(class_name, dist))distance_sorted = sorted(distance_dict.items(), key=lambda x:x[1])print ("识别到的人物最有可能是: ",distance_sorted[0][0].split('(')[0])font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(test_image, distance_sorted[0][0].split('(')[0], (int(test_image.shape[0]//2)-50,test_image.shape[1]-50), font, 0.8, (0, 0, 255), 3, cv2.LINE_AA)cv2.imshow('test_image', test_image)cv2.waitKey()

2.4结果展示

到这里,基于dlib的人脸识别就此结束了,接下来我们要用手动搭建网络的网络的方式,进行深度学习训练的方式来判定人脸的类别了。敬请期待

至此,敬礼,salute!!!

如果觉得《【Pytorch深度学习50篇】·······第二篇:【人脸识别】(2)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。