Python 3 利用 Dlib 實現人臉檢測和剪切


0. 引言

  利用 Python 開發,借助 Dlib 庫進行人臉檢測 / face detection 和剪切;

 

  1. crop_faces_show.py :

    將檢測到的人臉剪切下來,依次排序平鋪顯示在新的圖像上;

    實現的效果如 圖1 所示,將 圖1 原圖中的 6 張人臉檢測出來,然后剪切下來,在圖像窗口中依次輸出顯示人臉;

  2. crop_faces_save.py :

    將檢測到的人臉存儲為單個人臉圖像;

   

圖 1 原圖 和 crop_faces_show.py 處理后得到的平鋪人臉圖像窗口

 

  

圖 2 crop_faces_save.py 處理后得到的多個單張人臉圖像文件

 

  源碼上傳到了我的 Github;

  如果對您有幫助或者感興趣,歡迎 Star 支持下: https://github.com/coneypo/Dlib_face_cut

 

1. 開發環境

  Python:  3.6.3

  Dlib:    19.7

  OpenCv, NumPy

import dlib                 # 人臉檢測的庫 Dlib
import numpy as np         # 數據處理的庫 numpy
import cv2                  # 圖像處理的庫 OpenCv    

 

2. 實現過程

  工作內容主要以下兩大塊:Dlib 人臉檢測  處理檢測到的人臉圖像

2.1 Dlib 人臉檢測  

  利用已經訓練好的 Dlib 正向人臉檢測器 detector = dlib.get_frontal_face_detector() 進行人臉檢測;

  可以得到人臉外接矩形的坐標,用來之后進行裁剪;

  具體 Dlib 的使用,請參考我另一篇博客;

  ( link: Python 3 利用 Dlib 19.7 進行人臉檢測);

 1 # Dlib 檢測器
 2  detector = dlib.get_frontal_face_detector()
 3   
 4  # 讀取圖像
 5  path = "/***/image_path/"
 6  img = cv2.imread(path+"test_faces.jpg")
 7  # print("img/shape:", img.shape)
 8   
 9  # Dlib 檢測
10  faces = detector(img, 1)
11  
12  print("人臉數:", len(faces))

 

2.2 繪制新圖像

  如果你想讓檢測出來的人臉並排顯示的話,需要遍歷兩次( for k, d in enumerate (faces) ):

   第一次遍歷:記錄下我們需要生成的圖像窗口的大小,因為需要將多張照片顯示在一張圖像上,所以需要知道每張人臉照片的大小;

   第二次遍歷:根據之前得到的圖像尺寸新建空白圖像,然后開始用人臉矩形填充圖像;

 

2.2.1 確定空白圖像尺寸

( 這部分首先要根據檢測到的人臉數和人臉大小,來確定繪制圖像所需要的尺寸)  

第一次遍歷:多張人臉要輸出到一行,所以先進行一次人臉的遍歷j記下每張人臉的大小,記每張人臉的尺寸為 [ 高度 height  * 寬度 width ](高度和寬度說明見 圖 3 ):

圖 3 圖像尺寸說明

 

我取的生成空白圖像的尺寸:height_max(最大高度)和 width_sum(寬度之和),然后根據尺寸大小來新建空白圖像:

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 ):

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

    

  如果想訪問圖像的某點像素,可以利用 img [height] [width]:

    存儲像素其實是一個三維數組,先高度 height,然后寬度 width;

    返回的是一個顏色數組( 0-2550-2550-255 ),按照( B, G, )的順序;

    比如 藍色 就是(255,0,0),紅色 是(0,0,255);

 

3. 源碼

3.1 crop_faces_show.py

# created at 2018-01-22
# updated at 2018-09-29

# Author:   coneypo
# Blog:     http://www.cnblogs.com/AdaminXie
# GitHub:   https://github.com/coneypo/Dlib_face_cut

import dlib         # 人臉識別的庫dlib
import numpy as np  # 數據處理的庫numpy
import cv2          # 圖像處理的庫OpenCv

# Dlib 檢測器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')

# 讀取圖像
path = "faces_for_test/"
img = cv2.imread(path+"test_faces_1.jpg")

# Dlib 檢測
dets = detector(img, 1)

print("人臉數:", len(dets), "\n")

# 記錄人臉矩陣大小
height_max = 0
width_sum = 0

# 計算要生成的圖像 img_blank 大小
for k, d in enumerate(dets):

    # 計算矩形大小
    # (x,y), (寬度width, 高度height)
    pos_start = tuple([d.left(), d.top()])
    pos_end = tuple([d.right(), d.bottom()])

    # 計算矩形框大小
    height = d.bottom()-d.top()
    width = d.right()-d.left()

    # 處理寬度
    width_sum += width

    # 處理高度
    if height > height_max:
        height_max = height
    else:
        height_max = height_max

# 繪制用來顯示人臉的圖像的大小
print("窗口大小:"
      , '\n', "高度 / height:", height_max
      , '\n', "寬度 / width: ", width_sum)

# 生成用來顯示的圖像
img_blank = np.zeros((height_max, width_sum, 3), np.uint8)

# 記錄每次開始寫入人臉像素的寬度位置
blank_start = 0

# 將人臉填充到img_blank
for k, d in enumerate(dets):

    height = d.bottom()-d.top()
    width = d.right()-d.left()

    # 填充
    for i in range(height):
        for j in range(width):
                img_blank[i][blank_start+j] = img[d.top()+i][d.left()+j]
    # 調整圖像
    blank_start += width

cv2.namedWindow("img_faces")#, 2)
cv2.imshow("img_faces", img_blank)
cv2.waitKey(0

 

實現效果:

 

圖 5 原圖和處理后得到的圖像窗口

 

3.2 crop_faces_save.py

  如果你想將識別出來的人臉保存成單個的圖像,方便之后處理用,只需將上述代碼進行略微修改;

  只需一次遍歷,根據每次檢測到的人臉尺寸,新建空白圖像后寫入,然后利用 cv2.imwrite 寫入到本地:

  crop_faces_save.py:

 1 # created at 2018-01-22
 2 # updated at 2018-09-29
 3 
 4 # Author:   coneypo
 5 # Blog:     http://www.cnblogs.com/AdaminXie
 6 # GitHub:   https://github.com/coneypo/Dlib_face_cut
 7 
 8 import dlib         # 人臉識別的庫dlib
 9 import numpy as np  # 數據處理的庫numpy
10 import cv2          # 圖像處理的庫OpenCv
11 import os
12 
13 # 讀取圖像的路徑
14 path_read = "faces_for_test/"
15 img = cv2.imread(path_read+"test_faces_3.jpg")
16 
17 # 用來存儲生成的單張人臉的路徑
18 path_save = "faces_separated/"
19 
20 
21 # Delete old images
22 def clear_images():
23     imgs = os.listdir(path_save)
24 
25     for img in imgs:
26         os.remove(path_save + img)
27 
28     print("clean finish", '\n')
29 
30 
31 clear_images()
32 
33 
34 # Dlib 預測器
35 detector = dlib.get_frontal_face_detector()
36 predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
37 
38 
39 # Dlib 檢測
40 faces = detector(img, 1)
41 
42 print("人臉數:", len(faces), '\n')
43 
44 for k, d in enumerate(faces):
45 
46     # 計算矩形大小
47     # (x,y), (寬度width, 高度height)
48     pos_start = tuple([d.left(), d.top()])
49     pos_end = tuple([d.right(), d.bottom()])
50 
51     # 計算矩形框大小
52     height = d.bottom()-d.top()
53     width = d.right()-d.left()
54 
55     # 根據人臉大小生成空的圖像
56     img_blank = np.zeros((height, width, 3), np.uint8)
57 
58     for i in range(height):
59         for j in range(width):
60                 img_blank[i][j] = img[d.top()+i][d.left()+j]
61 
62     # cv2.imshow("face_"+str(k+1), img_blank)
63 
64     # 存在本地
65     print("Save to:", path_save+"img_face_"+str(k+1)+".jpg")
66     cv2.imwrite(path_save+"img_face_"+str(k+1)+".jpg", img_blank)

 

  

圖 6 生成的單個人臉圖像文件

 

# 請尊重他人勞動成果,轉載或者使用源碼請注明出處:http://www.cnblogs.com/AdaminXie

# 如果對您有幫助,歡迎在 GitHub 上 Star 本項目: https://github.com/coneypo/Dlib_face_cut

# 如有問題請留言或者聯系郵箱 coneypo@foxmail.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM