博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 3 利用 Dlib 实现人脸检测和剪切
阅读量:5010 次
发布时间:2019-06-12

本文共 5303 字,大约阅读时间需要 17 分钟。

0. 引言

  利用 Python 开发,借助 Dlib 库进行人脸检测 / face detection 和剪切;

 

  1.  :

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

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

  2.  :

    将检测到的人脸存储为单个人脸图像;

   

图 1 原图 和 crop_faces_show.py 处理后得到的平铺人脸图像窗口

 

  

图 2 crop_faces_save.py 处理后得到的多个单张人脸图像文件

 

  源码上传到了我的 Github;

  如果对您有帮助或者感兴趣,欢迎 Star 支持下: 

 

1. 开发环境

  Python:  3.6.3

  Dlib:    19.7

  OpenCv, NumPy

import dlib                 # 人脸检测的库 Dlibimport numpy as np         # 数据处理的库 numpyimport cv2                  # 图像处理的库 OpenCv

 

2. 实现过程

  工作内容主要以下两大块:Dlib 人脸检测  处理检测到的人脸图像

2.1 Dlib 人脸检测  

  利用已经训练好的 Dlib 正向人脸检测器 detector = dlib.get_frontal_face_detector() 进行人脸检测;

  可以得到人脸外接矩形的坐标,用来之后进行裁剪;

  具体 Dlib 的使用,请参考我另一篇博客;

  ( link: );

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_cutimport dlib         # 人脸识别的库dlibimport numpy as np  # 数据处理的库numpyimport 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 = 0width_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_blankfor 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 += widthcv2.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  # 数据处理的库numpy10 import cv2          # 图像处理的库OpenCv11 import os12 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 images22 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 生成的单个人脸图像文件

 

# 请尊重他人劳动成果,转载或者使用源码请注明出处:

# 如果对您有帮助,欢迎在 GitHub 上 Star 本项目: 

# 如有问题请留言或者联系邮箱 

转载于:https://www.cnblogs.com/AdaminXie/p/8339863.html

你可能感兴趣的文章
玩转storm
查看>>
第10章 使用Apache服务部署静态网站
查看>>
关于给予webApp框架的开发工具
查看>>
c语言编写的生成泊松分布随机数
查看>>
Maven入门笔记
查看>>
iOS webView的常见属性和方法
查看>>
理解position:relative
查看>>
Codeforces Round #344 (Div. 2) Messager KMP的应用
查看>>
20145308刘昊阳 《Java程序设计》第4周学习总结
查看>>
js倒计时
查看>>
EasyUI datagrid 格式 二
查看>>
Android虹软人脸识别sdk使用工具类
查看>>
UI:基础
查看>>
浅谈 @RequestParam 和@PathVariable
查看>>
设计模式之---装饰器设计模式
查看>>
基于WordNet的英文同义词、近义词相似度评估及代码实现
查看>>
Equation漏洞混淆利用分析总结(上)
查看>>
shell学习1shell简介
查看>>
Qt 【无法打开 xxxx头文件】
查看>>
JAVA项目将 Oracle 转 MySQL 数据库转换(Hibernate 持久层)
查看>>