前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Python使用dlib实现人脸检测

Python使用dlib实现人脸检测

作者头像
Awesome_Tang
发布于 2019-02-25 02:00:55
发布于 2019-02-25 02:00:55
1K00
代码可运行
举报
文章被收录于专栏:FSocietyFSociety
运行总次数:0
代码可运行
前期准备

在开始之前,你得先做如下准备:

  • opencv 这个一般没啥问题,通过pip install opencv-python安装即可。
  • dlib 安装dlib之前需要安装好cmake,之后再通过pip install dlib安装,如果报错的话,再自行百度吧,我是折腾了一下午才弄好。
  • 下载dlib提供的检测模型文件 下载地址:http://dlib.net/files/ 文件名shape_predictor_68_face_landmarks.dat
人脸检测
单一图片

代码部分实现起来非常简单,不过十几行的事,不过需要注意的是,通过cv2.imread读取的图片是BRG通道的,需要转成RGB通道,不然通过pyplot显示图片会变色。

  • 代码部分
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
import dlib
import matplotlib.pyplot as plt
import numpy as np

predictor_path = 'shape_predictor_68_face_landmarks.dat'
test_img = 'test.png'
img = cv2.imread(test_img)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)

faces = detector(img, 0)
if len(faces):
    print '==> Found %d face in this image.' % len(faces)
    for i in range(len(faces)):
        landmarks = np.matrix([[p.x, p.y] for p in predictor(img, faces[i]).parts()])
        for point in landmarks:
            pos = (point[0, 0], point[0, 1])
            cv2.circle(img, pos, 3, color=(0, 255, 0),thickness=3)
else:
    print 'Face not found!'

# opencv读取图片是BRG通道的,需要专成RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10, 8))
plt.subplot(121)
plt.imshow(plt.imread(test_img))
plt.axis('off')
plt.subplot(122)
plt.imshow(img)
plt.axis('off')
plt.show()
  • 效果如下

68点人脸检测

摄像头读取

我们可以通过cv2.VideoCapture(0)调起摄像头,camera.read会返回两个参数,第一个代表是否获取到图像帧,第二个代表图像帧内容,剩下的部分就跟上面一样了,传给dlib进行人脸检测就好了。

  • 完整代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding: utf-8 -*-

# @author: Awesome_Tang
# @date: 2018-12-31
# @version: python2.7

import cv2
import dlib
import numpy as np
import os


class Config(object):
    predictor_path = 'shape_predictor_68_face_landmarks.dat'
    test_img = 'test.jpg'
    width = 640
    height = 480


class FaceDetective():

    def __init__(self):
        self.detector = dlib.get_frontal_face_detector()
        self.predictor = dlib.shape_predictor(Config.predictor_path)

    def check_file(self,path):
        if os.path.exists(path):
            img = cv2.imread(path)
            return img
        else:
            raise IOError('No such file : "%s", please check!' % path)

    def detective(self, frame):
        faces = self.detector(frame, 0)
        if len(faces):
            print '==> Found %d face in this frame.' % len(faces)
            for i in range(len(faces)):
                landmarks = np.matrix([[p.x, p.y] for p in self.predictor(frame, faces[i]).parts()])
                for point in landmarks:
                    pos = (point[0, 0], point[0, 1])
                    cv2.circle(frame, pos, 3, color=(0, 0, 255),thickness=3)
        else:
            print 'Face not found!'
        return frame

    def run_camera(self):
        camera = cv2.VideoCapture(0)
        camera.set(cv2.CAP_PROP_FRAME_WIDTH, Config.width)
        camera.set(cv2.CAP_PROP_FRAME_HEIGHT, Config.height)
        while True:
            detected, frame = camera.read()

            if detected:
                frame = cv2.flip(frame, 1)
                frame = self.detective(frame)
            cv2.imshow("AwesomeTang", frame)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

        camera.release()
        cv2.destroyAllWindows()

    def single_image(self,img_path):
        img = self.check_file(img_path)
        img = self.detective(img)
        cv2.namedWindow("AwesomeTang", 0)
        cv2.resizeWindow("AwesomeTang", Config.width, Config.height)
        cv2.imshow("AwesomeTang",img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()


if __name__ == '__main__':
    p = FaceDetective()
    #p.single_image(Config.test_img)
    p.run_camera()
  • 效果如下

skr~ skr~~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.01.01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Oracle案例:ORA-00600: internal error code, arguments: [4187]
点击上方蓝色字关注我们~ 本案例客户来自某省电信,alert日志大量的ORA-00600[4187]报错,已经影响到业务正常运行。 Fri Nov 19 16:07:09 2021 Errors in file /u01/oracle/app/oracle/diag/rdbms/lcfa/LCFA1/trace/LCFA1_smon_5811.trc  (incident=184182): ORA-00600: internal error code, arguments: [4187], &#91
数据和云
2022/03/04
1.4K0
从裸机启动一个C++程序实战操作
对于一个C++程序员来说,可能更多是是每天都在跟各种上层语义、设计模式、软件方法等等在打交道。但对于「一个C++程序是如何运行在机器上的」这件事可能会比较陌生。有时,遇到一些问题,在宏观角度看起来可能比较难以解释,但其实从底层出发,就能发现这个问题其实根本不算问题。类似的问题有:
腾讯技术工程官方号
2024/03/30
8830
从裸机启动一个C++程序实战操作
Class文件字段表
在经历过了魔数(u4)、文件版本(u2+u2)、常量池(u2(常量池元素的数量)+具体字节数)、类访问标记(u2)、类索引(u2)、父类索引(u2)、接口(u2(接口的数量) + 具体的字节数)之后,我们便进入了类的内部,首先面对我们的便是字段(这里不分实例字段还是类字段),字段属性的具体接口如下:
shysh95
2021/01/03
1.1K0
Class文件字段表
再次和老李一起憋山寨Workerman(九)
今天接着昨天的socket_recv()继续编,上来就得先尝试解决一个问题:客户端每次发来的数据长度都是不固定的,怎么办?
老李秀
2020/01/17
8660
再次和老李一起憋山寨Workerman(九)
Java 类机制(3)---- 类文件结构
​ 在上一篇文章中我们一起来看了一下 Java 虚拟机的类加载过程,包括虚拟机加载、验证、准备、解析和初始化 5 个大步骤,同时我们还讨论了 Java 虚拟机加载类时采用的双亲委派模型思想。在这篇文章中我们来一起看一下 class 文件的结构,来进一步加深我们对虚拟机的类加载机制和类机制的理解。本文参考了 《深入理解 Java 虚拟机》一书。
指点
2019/07/01
6560
Java 类机制(3)---- 类文件结构
zigbee协议栈 任务、事件与轮询机制
typedef unsigned char uint8 只占一个字节,即二进制的8位,0b00000000,16进制的两位0x00;
全栈程序员站长
2022/09/02
4830
C语言结构体实例-创建兔子
参考裸编程思想。 #include <stdio.h> //#include "ycjobject.h" // 颜色定义 #define CL_BLACK 0 #define CL_WHITE 1 #define CL_GRAY 2 // 物种身份ID定义 #define ID_GRASS 0x0001 #define ID_CARROT 0x0002 #define ID_GREENVEGETABLE 0x0004 #define ID_RABBIT 0x00
用户4645519
2020/09/07
1K0
Class文件结构全面解析(下)
书接上一回,分享了Class文件的主要构成,同时也详细分析了魔数、次版本号、主版本号、常量池集合、访问标志的构造,接下来我们就继续学习。
万猫学社
2022/04/22
2760
Class文件结构全面解析(下)
扫描仪对接(C#)
源代码地址:http://www.codeproject.com/Articles/171666/Twain-for-WPF-Applications-Look-Ma-No-Handles
码客说
2022/09/19
4.7K0
扫描仪对接(C#)
C语言:内存字节对齐详解[转载]
一、什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 2. 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况, 但是最常见的是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为 32位)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低 字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。 二、对齐的实现 通常,我们写程序的时候,不需要考虑对齐问题。编译器会替我们选择适合目标平台的对齐策略。当然,我们也可以通知给编译器传递预编译指令而改变对指定数据的对齐方法。 但是,正因为我们一般不需要关心这个问题,所以因为编辑器对数据存放做了对齐,而我们不了解的话,常常会对一些问题感到迷惑。最常见的就是struct数据结构的sizeof结果,出乎意料。为此,我们需要对对齐算法所了解。 对齐的算法: 由于各个平台和编译器的不同,现以本人使用的gcc version 3.2.2编译器(32位x86平台)为例子,来讨论编译器对struct数据结构中的各成员如何进行对齐的。 设结构体如下定义: struct A { int a; char b; short c; }; 结构体A中包含了4字节长度的int一个,1字节长度的char一个和2字节长度的short型数据一个。所以A用到的空间应该是7字节。但是因为编译器要对数据成员在空间上进行对齐。 所以使用sizeof(strcut A)值为8。 现在把该结构体调整成员变量的顺序。 struct B { char b; int a; short c; }; 这时候同样是总共7个字节的变量,但是sizeof(struct B)的值却是12。 下面我们使用预编译指令#pragma pack (value)来告诉编译器,使用我们指定的对齐值来取代缺省的。 #progma pack (2) /*指定按2字节对齐*/ struct C { char b; int a; short c; }; #progma pack () /*取消指定对齐,恢复缺省对齐*/ sizeof(struct C)值是8。 修改对齐值为1: #progma pack (1) /*指定按1字节对齐*/ struct D { char b; int a; short c; }; #progma pack () /*取消指定对齐,恢复缺省对齐*/ sizeof(struct D)值为7。 对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。 这里面有四个概念值: 1)数据类型自身的对齐值:就是上面交代的基本数据类型的自身对齐值。 2)指定对齐值:#pragma pack (value)时的指定对齐值value。 3)结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。 4)数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值。 有了这些值,我们就可以很方便的来讨论具体数据结构的成员和其自身的对齐方式。有效对齐值N是最终用来决定数据存放地址方式的值,最重要。有效对齐N,就是表示“对齐在N上”,也就是说该数据的"存放起始地址%N=0".而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址就是 数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整 数倍,结合下面例子理解)。这样就不难理解上面的几个例子的值了。 例子分析: 分析例子B; struct B { char b; int a; short c; }; 假设B从地址空间0x0000开始排放。该例子中没有定义指定对齐值,在笔者环境下,该值默认为4。第一个成员变量b的自身对齐值是1,比指定或者默认指 定对齐值4小,所以其有效对齐值为1,所以其存放地址0x0000符合0x0000%1=0.第二个成员变量a,其自身对齐值为4,所以有效对齐值也为 4,所以只能存放在起始地址为0x0004到0x0007这四个连续的字节空
chain
2019/05/26
2.8K0
类索引和父类索引
类索引(this_class)和父类索引(super_class)都是一个u2类型的数据,类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类全限定名。由于java语言不允许多重继承,所以父类索引只有一个。
不会飞的小鸟
2020/06/14
8160
浅谈 Android Dex 文件
了解了 Dex 文件以后,对日常开发中遇到一些问题能有更深的理解。如:APK 的瘦身、热修复、插件化、应用加固、Android 逆向工程、64K 方法数限制。
有赞coder
2020/08/25
6840
浅谈 Android Dex 文件
【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译 Dex 文件 | 分析 Dex 文件反编译结果 )
Dalvik 虚拟机运行的是 Dex 文件 ; Dex 文件并不是最终 DVM 运行的文件 , Dex 文件还需要再次优化为 Odex 文件 , 这才是最终运行在 DVM 上的文件 ;
韩曙亮
2023/03/29
2.3K0
【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译 Dex 文件 | 分析 Dex 文件反编译结果 )
java类的class文件字节码解析
java语言:面向对象、静态类型、编译执行、有VM/GC和运行时、跨平台的高级语言。
冬天里的懒猫
2021/08/06
8970
JVM与字节码——2进制流字节码解析 原
本位将详细介绍字节码的2进制结构和JVM解析2进制流的规范。规范对字节码有非常严格的结构要求,其结构可以用一个JSON来描述:
随风溜达的向日葵
2018/08/15
1.1K0
《Java虚拟机原理图解》1.4 class文件中的字段表集合
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.csdn.net/article/details/41046443
亦山
2019/05/25
6310
2-MSP430按键输入检测
为了写一篇文章做铺垫--提醒着自己,,,,,, P1.0的电平,随着P1.1引脚输入的电平变化而变化 #include "io430.h" void delay(void) { unsigned char a,b,c; for(c=167;c>0;c--) for(b=171;b>0;b--) for(a=1;a>0;a--); } void main( void ) { WDTCTL = WDTPW + WDTHOLD;//看门狗默认是打开的,不使用
杨奉武
2018/04/18
1.2K0
2-MSP430按键输入检测
STUN协议解释[通俗易懂]
最近工作中要用到stun,故学习了一下stun协议的知识。中文的文档没找到讲的比较好的,所以只能自己翻译了,官方文档太长就找了个谷歌排名第一的文章翻译一下。机翻+人翻,原文地址如下,在学习过程中还发现了原文作者的一个错误。。。应该是他错了。
全栈程序员站长
2022/09/09
1.9K0
【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )
1 . 图像数据转换 : Camera 获取的是 NV21 格式的图像数据, 先将 NV21 格式的图像数据转为 I420 格式的图像数据 , 再将 I420 格式的图像数据编码为 H.264 格式的视频数据 ;
韩曙亮
2023/03/27
1.2K0
【Android RTMP】x264 编码器初始化及设置  ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )
dex文件解析(第三篇)「建议收藏」
dex文件是Android系统中的一种文件,是一种特殊的数据格式,和APK、jar 等格式文件类似。 能够被DVM识别,加载并执行的文件格式。 简单说就是优化后的android版.exe。每个apk安装包里都有。包含应用程序的全部操作指令以及运行时数据。 相对于PC上的java虚拟机能运行.class;android上的Davlik虚拟机能运行.dex。
全栈程序员站长
2022/08/03
1.6K0
dex文件解析(第三篇)「建议收藏」
推荐阅读
相关推荐
Oracle案例:ORA-00600: internal error code, arguments: [4187]
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文