1. 程式人生 > >Python 3 利用 Dlib 19.7 實現人臉檢測和剪下

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處理後得到單個人臉影象們

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的使用,在我之前另一篇部落格裡面介紹過

複製程式碼
 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)
複製程式碼

  


點選有驚喜