用dlib和opencv进行不同角度人脸检测及68个关键点提取(Python)

  • 用dlib和opencv进行不同角度人脸检测及68个关键点提取(Python)
  •  
  • 摘要:用dlib和opencv进行不同角度人脸检测及68个关键点提取(Python)前几日为了在自己的单个旋转人脸数据集上复现SDMforfaceAlignment算法,研究了用dlib机器学习工具箱和opencv进行旋转人脸的检测及关键点提取,整理一下思路,希望有所帮助。1.软件要求Ubuntu(Windows应该也适用)dlibopencv2Python+Numpy具体的安装过程不作详细介绍,可能要花些时间=.=2.程序介绍话不多说,直接上代码。a)导入函数importcv2i
  • 用dlib和opencv进行不同角度人脸检测及68个关键点提取(Python)

    前几日为了在自己的单个旋转人脸数据集上复现SDM for face Alignment算法,研究了用dlib机器学习工具箱和opencv进行旋转人脸的检测及关键点提取,整理一下思路,希望有所帮助。

    1. 软件要求
    • Ubuntu(Windows应该也适用)
    • dlib
    • opencv2
    • Python + Numpy

    具体的安装过程不作详细介绍,可能要花些时间 =.=

    2. 程序介绍

    话不多说,直接上代码。

    a) 导入函数

     

    import cv2import dlibimport numpyimport sysimport osfrom math import *

     

    b) 读取文件夹下的图片

     

    # 获取原始图片def getAllImg(folder): assert os.path.exists(folder) assert os.path.isdir(folder) imgList = os.listdir(folder) imgList = [item for item in imgList if os.path.isfile(os.path.join(folder, item))] return imgListimgList = getAllImg('me_1') print imgList # 打印所有的图片名

     

    得到me_1文件夹下的所有图片。

    c) 人脸检测及关键点提取

    首先,要下载dlib提供的已经训练好的关键点提取模型[链接]。因为我的人脸图片是不同角度的,所以不一定能够检测到人脸,所以当检测不到人脸时,依次旋转图片60度,再次检测,直到能够检测到人脸为止,如果旋转了360度还是检测不到人脸的话,那么认为该图片中不存在人脸。

     

    PREDICTOR_PATH = 'shape_predictor_68_face_landmarks.dat' # 关键点提取模型路径landmarks = [] # 存储人脸关键点# 1. 定义人脸检测器detector = dlib.get_frontal_face_detector()# 2. 载入关键点提取模型predictor = dlib.shape_predictor(PREDICTOR_PATH)have_face_img_num = 0 # 统计检测到人脸的图片个数print '*** Face detection start! ***' for img_name in imgList: im = cv2.imread('me_1/'+img_name) rotate_num = 0 # 旋转的次数 degree = 60 # 每次旋转的角度 while 1: rotate_num += 1 rects = detector(im, 1) # 检测人脸 if len(rects) >= 1: # 检测到人脸 have_face_img_num += 1 print ('img {}: rotating {} degree, get {} faces detected!'.format(img_name, degree*(rotate_num-1), len(rects))) row, col = im.shape[:2] if row > 600 and col > 600: # 如果图片太大,从中心位置取600×600的切片 im = im[row/2-300:row/2+300, col/2-300:col/2+300, :] rects = detector(im, 1) # 再次检测人脸框,一般还是可以检测到的,所以这里没判断 new_name = img_name.split('.')[0]+'_'+str(degree*(rotate_num-1))+'.png' # 重新命名图片,命名规则为原来的图片名+旋转角度 get_fea_points(rects, im, new_name) # 调用关键点子程序,见步骤d) cv2.imwrite('me2/'+new_name,im) # 保存图片到新的文件夹 break else: # 如果检测不到人脸 if rotate_num == int(360/degree): # 判断是否旋转完360度 print ('img {}: after rotate {} degree, No face is detected!'.format(img_name, degree*(rotate_num-1))) break # 旋转60度 rows, cols, channel = im.shape # 为了旋转之后不裁剪原图,计算旋转后的尺寸 rowsNew=int(cols*fabs(sin(radians(degree))) + rows*fabs(cos(radians(degree)))) colsNew=int(rows*fabs(sin(radians(degree))) + cols*fabs(cos(radians(degree)))) M = cv2.getRotationMatrix2D((cols/2, rows/2), degree, 1) # 旋转60度的仿射矩阵 M[0,2] +=(colsNew-cols)/2 M[1,2] +=(rowsNew-rows)/2 im = cv2.warpAffine(im, M, (colsNew, rowsNew), borderValue=(255,255,255)) # 旋转60度,得到新图片print ('*** success: {} / {}  ***'.format(have_face_img_num, len(imgList)))

     

    d) 保存68个关键点的子函数并依次显示

    将检测到的每张人脸的68个特征点保存到一个pts文件中。

     

    def get_fea_points(rects, im, new_name): global landmarks feas = [] # 关键点 fea_file_name = new_name[:-3] + 'pts' # pts文件名为旋转后图片名称.pts fea_file = open('me2/'+fea_file_name, 'a') # 新建pts文件 fea_file.write('version: 1'+'/n'+'n_points: 68'+'/n'+'{'+'/n') # 写入文件头部信息 for i in range(len(rects)): # 遍历所有检测到的人脸(我的是单个人脸) landmarks = numpy.matrix([[p.x, p.y] for p in predictor(im, rects[i]).parts()]) im = im.copy() # 使用enumerate 函数遍历序列中的元素以及它们的下标 for idx, point in enumerate(landmarks): pos = (point[0,0], point[0,1]) # 依次保存每个关键点 feas.append(pos) # 在图上画出关键点 cv2.circle(im, pos, 3, color=(0,255,0)) for pos in feas: fea_file.write(str(pos[0])+ ' '+ str(pos[1])+'/n') # 写如特征点到pts文件 fea_file.write('}') # 写pts文件尾部 fea_file.close() cv2.namedWindow("im", 2) # 显示标记特征点的图片 cv2.imshow("im", im) cv2.waitKey(0) 

     

    3. 实验结果

    读取原始图像,如果不能检测到人脸,依次旋转该图片以便检测到人脸,检测到人脸之后进行特征点提取:

                                    原图                                                                   旋转60度后的图                                                        关键点标记图

        用dlib和opencv进行不同角度人脸检测及68个关键点提取(Python)_Python   用dlib和opencv进行不同角度人脸检测及68个关键点提取(Python)_Python   用dlib和opencv进行不同角度人脸检测及68个关键点提取(Python)_Python

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用 OpenCVdlib 库实现截取眼睛和嘴巴的 Python 代码: ```python import cv2 import dlib # 加载模型 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') # 加载图像 img = cv2.imread('test.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测人脸 faces = detector(gray) # 遍历每张脸并截取眼睛和嘴巴 for face in faces: # 获取关键点 landmarks = predictor(gray, face) # 截取左眼 left_eye_pts = [(landmarks.part(36).x, landmarks.part(36).y), (landmarks.part(37).x, landmarks.part(37).y), (landmarks.part(38).x, landmarks.part(38).y), (landmarks.part(39).x, landmarks.part(39).y), (landmarks.part(40).x, landmarks.part(40).y), (landmarks.part(41).x, landmarks.part(41).y)] left_eye_mask = np.zeros(img.shape[:2], dtype=np.uint8) cv2.drawContours(left_eye_mask, [np.array(left_eye_pts)], -1, (255, 255, 255), -1, cv2.LINE_AA) left_eye = cv2.bitwise_and(img, img, mask=left_eye_mask) # 截取右眼 right_eye_pts = [(landmarks.part(42).x, landmarks.part(42).y), (landmarks.part(43).x, landmarks.part(43).y), (landmarks.part(44).x, landmarks.part(44).y), (landmarks.part(45).x, landmarks.part(45).y), (landmarks.part(46).x, landmarks.part(46).y), (landmarks.part(47).x, landmarks.part(47).y)] right_eye_mask = np.zeros(img.shape[:2], dtype=np.uint8) cv2.drawContours(right_eye_mask, [np.array(right_eye_pts)], -1, (255, 255, 255), -1, cv2.LINE_AA) right_eye = cv2.bitwise_and(img, img, mask=right_eye_mask) # 截取嘴巴 mouth_pts = [(landmarks.part(48).x, landmarks.part(48).y), (landmarks.part(49).x, landmarks.part(49).y), (landmarks.part(50).x, landmarks.part(50).y), (landmarks.part(51).x, landmarks.part(51).y), (landmarks.part(52).x, landmarks.part(52).y), (landmarks.part(53).x, landmarks.part(53).y), (landmarks.part(54).x, landmarks.part(54).y), (landmarks.part(55).x, landmarks.part(55).y), (landmarks.part(56).x, landmarks.part(56).y), (landmarks.part(57).x, landmarks.part(57).y), (landmarks.part(58).x, landmarks.part(58).y), (landmarks.part(59).x, landmarks.part(59).y), (landmarks.part(60).x, landmarks.part(60).y), (landmarks.part(61).x, landmarks.part(61).y), (landmarks.part(62).x, landmarks.part(62).y), (landmarks.part(63).x, landmarks.part(63).y), (landmarks.part(64).x, landmarks.part(64).y), (landmarks.part(65).x, landmarks.part(65).y), (landmarks.part(66).x, landmarks.part(66).y), (landmarks.part(67).x, landmarks.part(67).y)] mouth_mask = np.zeros(img.shape[:2], dtype=np.uint8) cv2.drawContours(mouth_mask, [np.array(mouth_pts)], -1, (255, 255, 255), -1, cv2.LINE_AA) mouth = cv2.bitwise_and(img, img, mask=mouth_mask) # 显示结果 cv2.imshow('Left Eye', left_eye) cv2.imshow('Right Eye', right_eye) cv2.imshow('Mouth', mouth) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上面的代码中,我们首先加载了训练好的人脸检测器和面部关键点检测器。然后,我们加载了一张图像,并将其转换为灰度图像。接下来,我们使用人脸检测器检测出图像中的所有人脸,并使用面部关键点检测器获取每个人脸的面部关键点。最后,我们根据面部关键点截取出眼睛和嘴巴的部分,并在窗口中显示结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值