0. 引言

  利用 Python 开发,借助 Dlib 库捕获摄像头中的人脸,进行实时人脸 68 个特征点标定;

  支持多张人脸;

  有截图功能;

 

图 1 工程效果示例( gif )

图 2 工程效果示例( 静态图片 )

1. 开发环境

  Python:  3.6.3

  Dlib:    19.7

  OpenCv, NumPy

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

2. 源码介绍

  其实实现很简单,主要分为两个部分:摄像头调用 + 人脸特征点标定

2.1 摄像头调用

  介绍下 OpenCv 中摄像头的调用方法,用到以下几个 OpenCv 函数:

    cv2.VideoCapture(0)               创建一个对象;

    cv2.VideoCapture.set(propId, value)  设置视频参数;

    cv2.VideoCapture.isOpened()     检测读取视频是否成功;

    cv2.VideoCapture.read()        返回是否读取成功和读取到的帧图像;

  (具体可以参考官方文档:https://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html

  关于 cv2 中 VideoCapture 类的一些函数参数的说明如下:

# Sort by coneypo
# Updated at 10, Oct
# Blog: http://www.cnblogs.com/AdaminXie ###### 1. cv2.VideoCapture(), 创建cv2摄像头对象 / Open the default camera ######
"""
Python: cv2.VideoCapture() → <VideoCapture object> Python: cv2.VideoCapture(filename) → <VideoCapture object>
filename – name of the opened video file (eg. video.avi) or image sequence (eg. img_%02d.jpg, which will read samples like img_00.jpg, img_01.jpg, img_02.jpg, ...) Python: cv2.VideoCapture(device) → <VideoCapture object>
device – id of the opened video capturing device (i.e. a camera index). If there is a single camera connected, just pass 0.
"""
cap = cv2.VideoCapture(0) ##### 2. cv2.VideoCapture.set(propId, value),设置视频参数; #####
"""
propId:
CV_CAP_PROP_POS_MSEC Current position of the video file in milliseconds.
CV_CAP_PROP_POS_FRAMES 0-based index of the frame to be decoded/captured next.
CV_CAP_PROP_POS_AVI_RATIO Relative position of the video file: 0 - start of the film, 1 - end of the film.
CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream.
CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream.
CV_CAP_PROP_FPS Frame rate.
...
value: 设置的参数值/ Value of the property
"""
cap.set(3, 480) ##### 3. cv2.VideoCapture.isOpened(), 检查摄像头初始化是否成功, 返回true或false / check if open camera successfully #####
cap.isOpened() ##### 4. cv2.VideoCapture.read([imgage]) -> retval,image, 读取视频 / Grabs, decodes and returns the next video frame #####
"""
返回两个值:
一个是布尔值true/false,用来判断读取视频是否成功/是否到视频末尾
图像对象,图像的三维矩阵
"""
flag, im_rd = cap.read()

2.2 人脸特征点标定

  调用预测器 “shape_predictor_68_face_landmarks.dat” 进行 68 点标定,这是 Dlib 训练好的模型,可以直接调用,进行人脸 68 个人脸特征点的标定;

  需要进行的后续工作是,利用坐标值进行特征点绘制;

  具体可以参考我的另一篇博客(Python 3 利用 Dlib 19.7 实现人脸68个特征点的标定);

 

图 3 Dlib 中人脸 68 个特征点位置说明

  

2.3 源码

  既然已经能够利用训练好的模型进行特征点检测,需要进行的工作是将摄像头捕获到的视频流,转换为 OpenCv 的图像对象,这样才能进行人脸特征点检测;

  然后利用返回的特征点坐标值,绘制特征点,实时的再绘制到摄像头界面上,达到实时人脸检测追踪的目的;

 

  利用 cv2.VideoCapture() 创建摄像头对象,然后利用 flag, im_rd = cv2.VideoCapture.read() 读取摄像头视频,im_rd 就是视频中的一帧帧图像;

  然后就类似于单张图像进行人脸检测,对这一帧帧的图像 im_rd 利用 Dlib 进行特征点标定,然后绘制特征点;

  

  可以按下 's' 键来获取当前截图,会存下带有时间戳的本地图像文件如 “screenshoot_1_2018-05-14-11-04-23.jpg”;

  或者按下 'q' 键来退出摄像头窗口;

  

  有四个 python 文件:

  how_to_use_camera.py    OpenCv 调用摄像头;

  get_features_from_image.py  绘制 "data/face_to_detect/face_x.jpg" 本地图像人脸文件的特征点;

  get_features_from_camera.py  从摄像头实时人脸检测绘制特征点;

  remove_ss.py:        删除 "data/screenshots/" 路径下的所有截图;

  ( 源码都上传到了 GitHub: https://github.com/coneypo/Dlib_face_detection_from_camera

  

  这里只给出 get_features_from_camera.py 的源码;

  get_features_from_camera.py:

 # 调用摄像头,进行人脸捕获,和 68 个特征点的追踪

 # Author:   coneypo
# Blog: http://www.cnblogs.com/AdaminXie
# GitHub: https://github.com/coneypo/Dlib_face_detection_from_camera # Created at 2018-02-26
# Updated at 2019-01-28 import dlib # 机器学习的库 Dlib
import numpy as np # 数据处理的库 numpy
import cv2 # 图像处理的库 OpenCv
import time
import timeit
import statistics # 储存截图的目录
path_screenshots = "data/screenshots/" detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('data/dlib/shape_predictor_68_face_landmarks.dat') # 创建 cv2 摄像头对象
cap = cv2.VideoCapture(0) # cap.set(propId, value)
# 设置视频参数,propId 设置的视频参数,value 设置的参数值
cap.set(3, 480) # 截图 screenshots 的计数器
cnt = 0 time_cost_list = [] # cap.isOpened() 返回 true/false 检查初始化是否成功
while cap.isOpened(): # cap.read()
# 返回两个值:
# 一个布尔值 true/false,用来判断读取视频是否成功/是否到视频末尾
# 图像对象,图像的三维矩阵
flag, im_rd = cap.read() # 每帧数据延时 1ms,延时为 0 读取的是静态帧
k = cv2.waitKey(1) # 取灰度
img_gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY) # start point
start = timeit.default_timer() # 人脸数
faces = detector(img_gray, 0) # print(len(faces)) # 待会要写的字体
font = cv2.FONT_HERSHEY_SIMPLEX # 标 68 个点
if len(faces) != 0:
# 检测到人脸
for i in range(len(faces)):
landmarks = np.matrix([[p.x, p.y] for p in predictor(im_rd, faces[i]).parts()]) for idx, point in enumerate(landmarks):
# 68 点的坐标
pos = (point[0, 0], point[0, 1]) # 利用 cv2.circle 给每个特征点画一个圈,共 68 个
cv2.circle(im_rd, pos, 2, color=(139, 0, 0)) # 利用 cv2.putText 输出 1-68
cv2.putText(im_rd, str(idx + 1), pos, font, 0.2, (187, 255, 255), 1, cv2.LINE_AA) cv2.putText(im_rd, "faces: " + str(len(faces)), (20, 50), font, 1, (0, 0, 0), 1, cv2.LINE_AA) # end point
stop = timeit.default_timer()
time_cost_list.append(stop - start)
print("%-15s %f" % ("Time cost:", (stop - start))) else:
# 没有检测到人脸
cv2.putText(im_rd, "no face", (20, 50), font, 1, (0, 0, 0), 1, cv2.LINE_AA) # 添加说明
im_rd = cv2.putText(im_rd, "press 'S': screenshot", (20, 400), font, 0.8, (255, 255, 255), 1, cv2.LINE_AA)
im_rd = cv2.putText(im_rd, "press 'Q': quit", (20, 450), font, 0.8, (255, 255, 255), 1, cv2.LINE_AA) # 按下 's' 键保存
if k == ord('s'):
cnt += 1
print(path_screenshots + "screenshot" + "_" + str(cnt) + "_" + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + ".jpg")
cv2.imwrite(path_screenshots + "screenshot" + "_" + str(cnt) + "_" + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + ".jpg", im_rd) # 按下 'q' 键退出
if k == ord('q'):
break # 窗口显示
# 参数取 0 可以拖动缩放窗口,为 1 不可以
# cv2.namedWindow("camera", 0)
cv2.namedWindow("camera", 1) cv2.imshow("camera", im_rd) # 释放摄像头
cap.release() # 删除建立的窗口
cv2.destroyAllWindows() print("%-15s" % "Result:")
print("%-15s %f" % ("Max time:", (max(time_cost_list))))
print("%-15s %f" % ("Min time:", (min(time_cost_list))))
print("%-15s %f" % ("Average time:", statistics.mean(time_cost_list)))

实时输出处理时间:

...
Time cost: 0.065273
Time cost: 0.059348
Time cost: 0.093570
Time cost: 0.091448
Time cost: 0.084946
Time cost: 0.089457
Time cost: 0.084367
Time cost: 0.094103
Time cost: 0.096082
Time cost: 0.073331
Time cost: 0.073685
Time cost: 0.065583
Time cost: 0.061161
Time cost: 0.061650
Time cost: 0.060952
Time cost: 0.084485 Result:
Max time: 0.112430
Min time: 0.057525
Average time: 0.085478

笔记本 CPU: i5-6200U@2.30GHz, Memory: 8G 处理时间平均在 0.08s;

# 请尊重他人劳动成果,转载或者使用源码请注明出处:http://www.cnblogs.com/AdaminXie

# 如果对您有帮助,欢迎在 GitHub 上 star 支持下: https://github.com/coneypo/Dlib_face_detection_from_camera

# 如有问题可以联系本人邮箱,商业合作勿扰谢谢: coneypo@foxmail.com

Python 3 利用 Dlib 实现摄像头人脸检测特征点标定的更多相关文章

  1. Python 3 利用 Dlib 实现摄像头实时人脸检测和平铺显示

    1. 引言 在某些场景下,我们不仅需要进行实时人脸检测追踪,还要进行再加工:这里进行摄像头实时人脸检测,并对于实时检测的人脸进行初步提取: 单个/多个人脸检测,并依次在摄像头窗口,实时平铺显示检测到的 ...

  2. Python 3 利用 Dlib 和 sklearn 人脸笑脸检测机器学习建模

    0. 引言 利用机器学习的方法训练微笑检测模型,输入一张人脸照片,判断是否微笑: 精度在 95% 左右( 使用的数据集中 69 张没笑脸,65 张有笑脸 ): 图1 测试图像与检测结果 项目实现的笑脸 ...

  3. Haar、pico、npd、dlib等多种人脸检测特征及算法结果比较

    原文:opencv.pico.npd.dlib.face++等多种人脸检测算法结果比较 NDP检测结果: 结果分析: Pico(Pixel Intensity Comparison-based Obj ...

  4. Python 3 利用 Dlib 19.7 实现摄像头人脸识别

    0.引言 利用python开发,借助Dlib库捕获摄像头中的人脸,提取人脸特征,通过计算欧氏距离来和预存的人脸特征进行对比,达到人脸识别的目的: 可以自动从摄像头中抠取人脸图片存储到本地: 根据抠取的 ...

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

    0. 引言 利用 Python 开发,借助 Dlib 库进行人脸检测 / face detection 和剪切:   1. crop_faces_show.py : 将检测到的人脸剪切下来,依次排序平 ...

  6. Python 3 利用 Dlib 19.7 实现人脸识别和剪切

    0.引言 利用python开发,借助Dlib库进行人脸识别,然后将检测到的人脸剪切下来,依次排序显示在新的图像上: 实现的效果如下图所示,将图1原图中的6张人脸检测出来,然后剪切下来,在图像窗口中依次 ...

  7. Python 3 利用 Dlib 19.7 和 sklearn机器学习模型 实现人脸微笑检测

    0.引言  利用机器学习的方法训练微笑检测模型,给一张人脸照片,判断是否微笑:   使用的数据集中69张没笑脸,65张有笑脸,训练结果识别精度在95%附近: 效果: 图1 示例效果 工程利用pytho ...

  8. Python 3 利用 Dlib 19.7 进行人脸检测

    0. 引言 / Overview 介绍 Dlib 中基于 HOG,Histogram of Oriented Gradients / 方向梯度直方图 实现 Face Detect / 人脸检测 的两个 ...

  9. Python 3 利用 Dlib 实现人脸 68个 特征点的标定

    0. 引言 利用 Dlib 官方训练好的模型 “shape_predictor_68_face_landmarks.dat” 进行 68 个点标定: 利用 OpenCv 进行图像化处理,在人脸上画出 ...

随机推荐

  1. Gradle Goodness: Parse Files with SimpleTemplateEngine in Copy Task

    With the copy task of Gradle we can copy files that are parsed by Groovy's SimpleTemplateEngine. Thi ...

  2. Vscode 格式化vue Template代码段

    1.安装 vetur 2.在User Setting中增加设置: "vetur.format.defaultFormatter.html": "js-beautify-h ...

  3. 【HTML-进阶-如何实现父级块级元素宽度自适应子元素宽度】

    背景 块级元素宽度默认值为100%,而不是auto;因此其宽度不会根据子元素内容动态适应. 如何实现父级元素宽度动态适应其子元素. 方法一 display:inline; 给块级元素设置inline- ...

  4. Vcenter虚拟化三部曲----Vcenter server 5.5安装部署

    配置SQL Server 2008 R2 1.选择启动 SQL Server Management Studio. 2.选择SQL Server 身份验证登录 ---- 输入sa用户及密码. 3.右键 ...

  5. Oracle索引实现方式

  6. 读取本地json文件另一种方式

    function getScenemapData(){ $.ajax({     url: "/js/currency.json",    type: "GET" ...

  7. Linux基础-5.利用vi编辑器创建和编辑正文文件

    1.vi编辑器简介 1)掌握vi编辑器的定义:vi编辑器是Linux和Unix上最基本的文本编辑器,工作在字符模式下.由于不需要图形界面,vi是效率很高的文本编辑器.尽管在Linux上也有很多图形界面 ...

  8. MySQL----navicat for mysql(破解版)可视化数据库操作

    本博文介绍破解版navicat for mysql的安装方法及常用操作 navicat for mysql是一个专业的MySQL数据库图形化界面工具. 百度云下载地址:https://pan.baid ...

  9. [试玩] FMXLinux (Firemonkey for Linux) Linux 桌面开发(第三方插件)

    FMXLinux 是一个可以用来开发 Linux 桌面软件的第三方插件,它需要配合 Delphi 10.2 Toyko 官网:http://www.fmxlinux.com/ 使用方法:开启 FMX ...

  10. Python-条件语句和循环语句

    ·条件语句 笔记: If  布尔值: print(‘hello,world!’) 当表达式为布尔表达式时,Flase   None  0   ””    ()    []    {} 都视为假! @ ...