Python 3 利用 Dlib 19.7 实现人脸检测和剪切

  1. 云栖社区>
  2. 博客>
  3. 正文

Python 3 利用 Dlib 19.7 实现人脸检测和剪切

隐士2018 2018-03-01 16:14:04 浏览2857
展开阅读全文

Python 3 利用 Dlib 19.7 实现人脸检测和剪切

0.引言

   利用python开发,借助Dlib库进行人脸检测/face detection;

   1. dlib_cut_faces.py : 

    将检测到的人脸剪切下来,依次排序显示在新的图像上;

    实现的效果如图1所示,将图1原图中的6张人脸检测出来,然后剪切下来,在图像窗口中依次输出显示人脸;

   2. dlib_cut_faces_save.py:

    将检测到的人脸生成单个jpg,存储到本地路径;

 

   (实现比较简单,代码量也比较少,适合入门或者兴趣学习。)

   

    图1 原图和dlib_cut_faces.py处理后得到的图像窗口

 

  

    图2 dlib_cut_faces_save.py处理后得到单个人脸图像们

 

  源码上传到了我的Github,如果对您有帮助或者感兴趣,欢迎Star支持下: https://github.com/coneypo/Dlib_face_cut

 

1.开发环境

  python:  3.6.3

  dlib:    19.7

  OpenCv, numpy

 

1 import dlib         # 人脸识别的库dlib
2 import numpy as np  # 数据处理的库numpy
3 import cv2          # 图像处理的库OpenCv

 

2.设计流程

  工作内容主要以下两大块:dlib人脸检测 和 绘制新图像

  2.1 dlib人脸检测

    dlib的使用,在我之前另一篇博客里面介绍过

    (link: http://www.cnblogs.com/AdaminXie/p/7905888.html);

复制代码
 1 # dlib检测器
 2 detector = dlib.get_frontal_face_detector()
 3 predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
 4 
 5 # 读取图像
 6 path = "F:/***/pic/"
 7 img = cv2.imread(path+"test_faces_6.jpg")
 8 #print("img/shape:", img.shape)
 9 
10 # dlib检测
11 dets = detector(img, 1)
12 
13 print("人脸数:", len(dets))
复制代码

     接下来需要得到人脸的坐标,用来计算人脸矩形的高度和宽度。

 

  2.2 绘制新图像

     如果你想让人脸并排显示的话,稍微麻烦一点,需要遍历两次dets(for k, d in enumerate (dets)):

   第一次遍历:记录下我们需要生成的图像窗口的大小,因为需要将多张照片显示在一张图像上,所以需要知道每张人脸照片的大小;

   第二次遍历:根据之前得到的图像尺寸新建空白图像,然后开始用人脸矩形填充图像;

 

  2.2.1 确定空白图像尺寸

  (这部分首先要根据检测到的人脸数和人脸大小,来确定绘制图像所需要的尺寸)  

第一次遍历:多张人脸要输出到一行,所以先进行一次人脸的遍历j记下每张人脸的大小,记每张人脸的尺寸为 高度height  *宽度width(高度和宽度说明见图3):

    图3 图像尺寸说明

 

我取的生成空白图像的尺寸:height_max(最大高度)和width_sum(宽度之和),然后根据尺寸大小来新建空白图像:

1 img_blank = np.zeros((height_max, width_sum, 3), np.uint8)

    图4 图像尺寸height_max和width_sum

 

  2.2.2 图像填充

  第二次遍历:多根据之前得到的图像尺寸新建空白图像,然后开始用人脸矩形填充图像,每次width方向从blank_start位置开始,每次填完一张之后记得更新起始位置:(blank_start += width):

1 for i in range(height):
2     for j in range(width):
3         img_blank[i][blank_start + j] = img[d.top() + i][d.left() + j]

  

  

  如果想访问图像的某点像素,可以利用img[height][width]:

    存储像素其实是一个三维数组,先高度height,然后宽度width;

    返回的是一个颜色数组(0-255,0-255,0-255),按照(B, G, R)的顺序;

    比如 蓝色 就是(255,0,0),红色 是(0,0,255);

 

3.源码

3.1 dlib_cut_faces.py

复制代码
 1 # 2018-01-22
 2 # By TimeStamp
 3 # #cnblogs: http://www.cnblogs.com/AdaminXie/
 4 
 5 import dlib         # 人脸识别的库dlib
 6 import numpy as np  # 数据处理的库numpy
 7 import cv2          # 图像处理的库OpenCv
 8 
 9 # dlib预测器
10 detector = dlib.get_frontal_face_detector()
11 predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
12 
13 # 读取图像
14 path = "F:/code/python/***/pic/"
15 img = cv2.imread(path+"test.jpg")
16 #print("img/shape:", img.shape)
17 
18 # dlib检测
19 dets = detector(img, 1)
20 
21 print("人脸数:", len(dets))
22 
23 # 记录人脸矩阵大小
24 height_max = 0
25 width_sum = 0
26 
27 # 计算要生成的图像img_blank大小
28 for k, d in enumerate(dets):
29 
30     # 计算矩形大小
31     # (x,y), (宽度width, 高度height)
32     pos_start = tuple([d.left(), d.top()])
33     pos_end = tuple([d.right(), d.bottom()])
34 
35     # 计算矩形框大小
36     height = d.bottom()-d.top()
37     width = d.right()-d.left()
38 
39     # 处理宽度
40     width_sum += width
41 
42     # 处理高度
43     if height > height_max:
44         height_max = height
45     else:
46         height_max = height_max
47 
48 # 绘制用来显示人脸的图像的大小
49 print("img_blank的大小:")
50 print("高度", height_max, "宽度", width_sum)
51 
52 # 生成用来显示的图像
53 img_blank = np.zeros((height_max, width_sum, 3), np.uint8)
54 
55 # 记录每次开始写入人脸像素的宽度位置
56 blank_start = 0
57 
58 # 将人脸填充到img_blank
59 for k, d in enumerate(dets):
60 
61     height = d.bottom()-d.top()
62     width = d.right()-d.left()
63 
64     # 填充
65     for i in range(height):
66         for j in range(width):
67                 img_blank[i][blank_start+j] = img[d.top()+i][d.left()+j]
68     # 更新读取图像起始位置
69     blank_start += width
70 
71 cv2.namedWindow("img_faces", 2)
72 cv2.imshow("img_faces", img_blank)
73 cv2.waitKey(0)
复制代码

 

 

结果:

 

    图5 原图和处理后得到的图像窗口

 

3.2 dlib_cut_faces_save.py

  如果你想将识别出来的人脸保存成单个的jpg,方便之后处理用,只需将上述代码进行略微修改;

只需一次遍历,根据每次检测到的人脸尺寸,新建空白图像后写入,然后利用cv2.imwrite写入到本地:

复制代码
 1 # 2018-01-24
 2 # By TimeStamp
 3 # #cnblogs: http://www.cnblogs.com/AdaminXie/
 4 
 5 import dlib         # 人脸识别的库dlib
 6 import numpy as np  # 数据处理的库numpy
 7 import cv2          # 图像处理的库OpenCv
 8 
 9 # dlib预测器
10 detector = dlib.get_frontal_face_detector()
11 predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
12 
13 # 读取图像的路径
14 path_read = "F:/************/pic/"
15 img = cv2.imread(path_read+"test.jpg")
16 
17 # 用来存储生成的单张人脸的路径
18 path_save = "F:/**********/pic/"
19 
20 # dlib检测
21 dets = detector(img, 1)
22 
23 print("人脸数:", len(dets))
24 
25 for k, d in enumerate(dets):
26 
27     # 计算矩形大小
28     # (x,y), (宽度width, 高度height)
29     pos_start = tuple([d.left(), d.top()])
30     pos_end = tuple([d.right(), d.bottom()])
31 
32     # 计算矩形框大小
33     height = d.bottom()-d.top()
34     width = d.right()-d.left()
35 
36     # 根据人脸大小生成空的图像
37     img_blank = np.zeros((height, width, 3), np.uint8)
38 
39     for i in range(height):
40         for j in range(width):
41                 img_blank[i][j] = img[d.top()+i][d.left()+j]
42 
43     cv2.imshow("face_"+str(k+1), img_blank)
44     cv2.imwrite(path_save+"img_face_"+str(k+1)+".jpg", img_blank)
45 
46 cv2.waitKey(0)
复制代码

 

  

    图6 生成的单个人脸jpg


转自:http://www.cnblogs.com/AdaminXie/p/8339863.html

网友评论

登录后评论
0/500
评论
隐士2018
+ 关注