计算机视觉之dlib人脸关键点绘制及微笑测试
dlib人脸关键点绘制及微笑测试
目录
- dlib人脸关键点绘制及微笑测试
- 1 dlib人脸关键点
- 1.1 dlib
- 1.2 人脸关键点检测
- 1.3 检测模型
- 1.4 凸包
- 1.5 笑容检测
- 1.6 函数
- 2 人脸检测代码
- 2.1 关键点绘制
- 2.2 关键点连线
- 2.3 微笑检测
1 dlib人脸关键点
1.1 dlib
dlib 是一个强大的机器学习库,广泛用于人脸检测和人脸关键点检测。它提供了一个预训练的 68 点人脸关键点检测模型,可以准确地定位人脸的各个部位(如眼睛、鼻子、嘴巴等)
1.2 人脸关键点检测
dlib 的 68 点人脸关键点检测模型基于 HOG(Histogram of Oriented Gradients)特征和线性分类器,结合了形状预测算法。它可以检测人脸的以下区域:
下巴(0-16)
右眉毛(17-21)
左眉毛(22-26)
鼻子(27-35)
右眼(36-41)
左眼(42-47)
嘴巴(48-67)

1.3 检测模型
dlib 提供了一个预训练的 68 点人脸关键点检测模型,可以从以下链接下载:
https://github.com/davisking/dlib-models/blob/master/shape_predictor_68_face_landmarks.dat.bz2/
1.4 凸包
凸包(Convex Hull) 是计算几何中的一个重要概念,指的是在二维或更高维空间中,包含一组点的最小凸多边形或凸多面体。凸包在图像处理、计算机视觉、模式识别等领域有广泛应用,例如在人脸关键点检测中,可以用凸包来定义人脸区域的边界。
1.5 笑容检测
定义了两个函数,MAR:衡量嘴巴的张开程度,
和MJR:衡量嘴巴宽度与下巴宽度的比例,
人脸关键点如上,当微笑时嘴巴长款和脸颊长度都会发生改变,通过两个函数进行比较检测,进行判断是否微笑
def MAR(shape):x = shape[50]y = shape[50].reshape(1,2)A = euclidean_distances(shape[50].reshape(1,2),shape[58].reshape(1,2))B = euclidean_distances(shape[51].reshape(1,2),shape[57].reshape(1,2))C = euclidean_distances(shape[52].reshape(1,2),shape[56].reshape(1,2))D = euclidean_distances(shape[48].reshape(1,2),shape[54].reshape(1,2))return ((A+B+C)/3)/Ddef MJR(shape):M = euclidean_distances(shape[48].reshape(1,2),shape[54].reshape(1,2))J = euclidean_distances(shape[3].reshape(1,2),shape[13].reshape(1,2))return M/J
1.6 函数
- detector = dlib.get_frontal_face_detector() ,加载人脸检测器
- predictor = dlib.shape_predictor(‘shape_predictor_68_face_landmarks.dat’) 关键点预测器
- detector(gray, 1) ,检测人脸
- gray检测的灰度图
- 1 表示对图像进行上采样次数
2 人脸检测代码
2.1 关键点绘制
代码展示:
import cv2
import numpy as np
import dlibimg = cv2.imread('lyf.png')
detector = dlib.get_frontal_face_detector()
faces = detector(img,0)
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
for face in faces:shape = predictor(img,face)landmarks = np.array([[p.x,p.y] for p in shape.parts()])for idx,point in enumerate(landmarks):pos = [point[0],point[1]]cv2.circle(img,pos,2,color=(0,255,0),thickness=-1)cv2.putText(img,str(idx),pos,cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,0.4,(255,255,255),1,cv2.LINE_AA)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:

2.2 关键点连线
代码展示:
import cv2
import numpy as np
import dlibdef drawLine(start,end):pts = shape[start:end]for l in range(1,len(pts)):pta = tuple(pts[l-1])ptb = tuple(pts[l])cv2.line(img,pta,ptb,(0,255,0),1)def drawConvexHull(start,end):facial = shape[start:end+1]mouthHull = cv2.convexHull(facial)cv2.drawContours(img,[mouthHull],-1,(0,255,0),1)img = cv2.imread('lyf.png')
detector = dlib.get_frontal_face_detector()
faces = detector(img,0)
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
for face in faces:shape = predictor(img,face)shape = np.array([[p.x,p.y] for p in shape.parts()])drawConvexHull(36,41)drawConvexHull(42,47)drawConvexHull(48, 59)drawConvexHull(60, 67)drawLine(0,17)drawLine(17, 22)drawLine(22, 27)drawLine(27, 36)cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:

2.3 微笑检测
代码展示:
import cv2
import numpy as np
import dlib
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
v = cv2.VideoCapture('jjy_dyx.mp4')
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image, ImageDraw, ImageFontdef cv2AddChineseText(img, text, position, textColor=(255, 255, 255), textSize=30):""" 向图片中添加中文 """if (isinstance(img, np.ndarray)): # 判断是否OpenCV图片类型img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))#实现array到image的转换draw = ImageDraw.Draw(img)# 在img图片上创建一个绘图的对象# 字体的格式fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")draw.text(position, text, textColor, font=fontStyle) # 绘制文本return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)# 转换回OpenCV格式def MAR(shape):x = shape[50]y = shape[50].reshape(1,2)A = euclidean_distances(shape[50].reshape(1,2),shape[58].reshape(1,2))B = euclidean_distances(shape[51].reshape(1,2),shape[57].reshape(1,2))C = euclidean_distances(shape[52].reshape(1,2),shape[56].reshape(1,2))D = euclidean_distances(shape[48].reshape(1,2),shape[54].reshape(1,2))return ((A+B+C)/3)/Ddef MJR(shape):M = euclidean_distances(shape[48].reshape(1,2),shape[54].reshape(1,2))J = euclidean_distances(shape[3].reshape(1,2),shape[13].reshape(1,2))return M/Jwhile True:r,img = v.read()if not r:breakfaces = detector(img,0)for face in faces:shape = predictor(img,face)shape= np.array([[p.x,p.y] for p in shape.parts()])mar = MAR(shape)mjr =MJR(shape)result = '正常'print('mar:',mar,'mjr:',mjr)if mar>0.5:result = '大笑'elif mjr>0.4:result = '微笑'mouthHull = cv2.convexHull(shape[48:61])img = cv2AddChineseText(img,result,mouthHull[0,0],1)cv2.drawContours(img,[mouthHull],-1,(0,255,0),1)cv2.imshow('img', img)key = cv2.waitKey(1)if key == 32:break
v.release()
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:

相关文章:
计算机视觉之dlib人脸关键点绘制及微笑测试
dlib人脸关键点绘制及微笑测试 目录 dlib人脸关键点绘制及微笑测试1 dlib人脸关键点1.1 dlib1.2 人脸关键点检测1.3 检测模型1.4 凸包1.5 笑容检测1.6 函数 2 人脸检测代码2.1 关键点绘制2.2 关键点连线2.3 微笑检测 1 dlib人脸关键点 1.1 dlib dlib 是一个强大的机器学习库&a…...
FPGA时序约束的几种方法
一,时钟约束 时钟约束是最基本的一个约束,因为FPGA工具是不知道你要跑多高的频率的,你必要要告诉工具你要跑的时钟频率。时钟约束也就是经常看到的Fmax,因为Fmax是针对“最差劲路径”,也就是说,如果该“最差劲路径”得到好成绩,那些不是最差劲的路径的成绩当然比…...
【0013】Python数据类型-列表类型详解
如果你觉得我的文章写的不错,请关注我哟,请点赞、评论,收藏此文章,谢谢! 本文内容体系结构如下: Python列表,作为编程中的基础数据结构,扮演着至关重要的角色。它不仅能够存储一系…...
10.RabbitMQ集群
十、集群与高可用 RabbitMQ 的集群分两种模式,一种是默认集群模式,一种是镜像集群模式; 在RabbitMQ集群中所有的节点(一个节点就是一个RabbitMQ的broker服务器) 被归为两类:一类是磁盘节点,一类是内存节点; 磁盘节点会把集群的所有信息(比如交换机、绑…...
Web网页开发——水果忍者
1.介绍 复刻经典小游戏——水果忍者 2.预览 3.代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&…...
信息安全访问控制、抗攻击技术、安全体系和评估(高软42)
系列文章目录 信息安全访问控制、抗攻击技术、安全体系和评估 文章目录 系列文章目录前言一、信息安全技术1.访问控制2.抗攻击技术 二、欺骗技术1.ARP欺骗2.DNS欺骗3.IP欺骗 三、抗攻击技术1.端口扫描2.强化TCP/IP堆栈 四、保证体系和评估1.保证体系2.安全风险管理 五、真题在…...
【算法】009、单双链表反转
【算法】009、单双链表反转 文章目录 一、单链表反转1.1 实现思路1.2 多语言解法 二、双链表反转2.1 实现思路2.2 多语言解法 一、单链表反转 1.1 实现思路 维护 pre 变量。 从前向后遍历 head,首先记录 next head.next,其次反转指针使 head.next pr…...
物联网设备接入系统后如何查看硬件实时数据?
要在软件中实时查看硬件设备的信息,通常需要结合前后端技术来实现。以下是设计思路和实现步骤: 1. 系统架构设计 实时查看硬件设备信息的系统通常采用以下架构: 数据采集层: 硬件设备通过传感器采集数据,发送到InfluxDB。数据存…...
【Linux系统编程】初识系统编程
目录 一、什么是系统编程1. 系统编程的定义2. 系统编程的特点3. 系统编程的应用领域4. 系统编程的核心概念5. 系统编程的工具和技术 二、操作系统四大基本功能1. 进程管理(Process Management)2. 内存管理(Memory Management)3. 文…...
解决stylelint对deep报错
报错如图 在.stylelintrc.json的rules中配置 "selector-pseudo-class-no-unknown": [true,{"ignorePseudoClasses": ["deep"]} ]...
React基础之useInperativehandlle
通过ref调用子组件内部的focus方法来实现聚焦 与forwardRef类似,但是forwardRef是通过暴露整个Ref来实现,而useInperativehandle是通过对外暴露一个方法来实现的 import { forwardRef, useImperativeHandle, useRef, useState } from "react";…...
使用joblib 多线程/多进程
文章目录 1. Joblib 并行计算的两种模式多进程(Multiprocessing,适用于 CPU 密集型任务)多线程(Multithreading,适用于 I/O 密集型任务)2. Joblib 的基本用法3. Joblib 多进程示例(适用于 CPU 密集型任务)示例:计算平方4. Joblib 多线程示例(适用于 I/O 密集型任务)…...
⭐算法OJ⭐N-皇后问题 II【回溯剪枝】(C++实现)N-Queens II
⭐算法OJ⭐N-皇后问题【回溯剪枝】(C实现)N-Queens 问题描述 The n-queens puzzle is the problem of placing n n n queens on an n n n \times n nn chessboard such that no two queens attack each other. Given an integer n, return the num…...
【数据结构初阶】---堆的实现、堆排序以及文件中的TopK问题
1.树的概念及结构 1.1树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点&…...
ubuntu20系统下conda虚拟环境下安装文件存储位置
在 Conda 虚拟环境中执行 pip install 安装软件后,安装的文件会存储在该虚拟环境专属的 site-packages 目录中。具体路径取决于你激活的 Conda 环境路径。以下是定位步骤: 1. 确认 Conda 虚拟环境的安装路径 查看所有环境: conda info --env…...
鸿蒙开发:RelativeContainer 相对布局详解【全套华为认证学习资料分享(考试大纲、培训教材、实验手册等等)】
前言 在最新版本的 DevEco Studio 中,官方在创建新项目时,默认使用 RelativeContainer 组件作为根布局。这足以证明 RelativeContainer 的重要性。相比其他容器组件,它极大地简化了复杂 UI 布局中的元素对齐问题。 例如,在没有 R…...
基于SpringBoot实现旅游酒店平台功能一
一、前言介绍: 1.1 项目摘要 随着社会的快速发展和人民生活水平的不断提高,旅游已经成为人们休闲娱乐的重要方式之一。人们越来越注重生活的品质和精神文化的追求,旅游需求呈现出爆发式增长。这种增长不仅体现在旅游人数的增加上࿰…...
HttpServletRequest 和 HttpServletResponse 区别和作用
一、核心作用对比 对象HttpServletRequest(请求对象)HttpServletResponse(响应对象)本质客户端发给服务器的 HTTP 请求信息(输入)服务器返回客户端的 HTTP 响应信息(输出)生命周期一…...
树莓派学习(一)——3B+环境配置与多用户管理及编程实践
树莓派学习(一)——3B环境配置与多用户管理及编程实践 一、实验目的 掌握树莓派3B无显示器安装与配置方法。学习Linux系统下多用户账号的创建与管理。熟悉在树莓派上使用C语言和Python3编写简单程序的方法。 二、实验环境 硬件设备:树莓派…...
Mysql安装方式
方式一:安装包安装 下载安装包 官网直接下载:https://dev.mysql.com/downloads/ 安装配置 2.1、双击刚刚下载好的msi文件,开始安装MySQL。 2.2、选择自定义模式Custom安装 2.3、点击选择自己电脑对应的mysql安装目录 2.5、继续点击下一步&…...
OpenClaw成本优化方案:ollama GLM-4.7-Flash自建模型接口实践
OpenClaw成本优化方案:ollama GLM-4.7-Flash自建模型接口实践 1. 为什么需要关注OpenClaw的token消耗问题 第一次用OpenClaw完成自动化周报任务时,我盯着账单倒吸一口凉气——生成三份周报竟然消耗了接近15万token。这让我意识到,如果不解决…...
【调试心法】别用 printf 谋杀你的系统了!打破“测不准”魔咒,用 C++ 与 DMA 构筑微秒级零开销异步观测者
摘要:在硬实时控制系统中,最可怕的 Bug 往往是薛定谔的 Bug——当你试图用 printf 去观察它时,观察行为本身产生的巨大延迟,就足以改变系统的物理运行轨迹。本文将无情揭露同步串口打印的耗时真相,批判阻塞式调试对高频…...
【英飞凌】TC3XX单片机型号解码:从命名规则看芯片选型
1. 英飞凌TC3XX单片机命名规则解析 第一次接触英飞凌TC3XX系列单片机时,我完全被那一长串型号搞懵了。TC387TP、TC377T、TC397QP...这些看似随机的字母数字组合,其实隐藏着丰富的芯片信息。经过几个项目的实战,我终于摸清了这套命名规则的规律…...
进阶篇第5节:共享内存(三)——实战:优化矩阵乘法(Tiling技术)
第二篇进阶篇第5节:共享内存(三)——实战:优化矩阵乘法(Tiling技术) 从朴素到分块,从分块到极致——矩阵乘法的优化之路,就是CUDA性能优化的缩影 写在前面 矩阵乘法是CUDA优化中最经典的案例,没有之一。在筑基篇,我们实现了朴素版本和基础分块版本,性能从 252 GFLO…...
OpenClaw跨平台实战:Windows到Mac的Qwen3-32B配置迁移
OpenClaw跨平台实战:Windows到Mac的Qwen3-32B配置迁移 1. 为什么需要跨平台配置迁移? 去年冬天,我在Windows工作站上搭建了一套基于Qwen3-32B的OpenClaw自动化系统,用于处理日常的文档整理和数据分析任务。当公司配发新款MacBoo…...
半导体晶圆测量中的5大常见误区:从台阶仪到无图晶圆系统的避坑指南
半导体晶圆测量中的5大常见误区:从台阶仪到无图晶圆系统的避坑指南 在半导体制造领域,晶圆测量是确保器件性能与良率的关键环节。然而,即使是经验丰富的工程师,也常因忽视某些细节而陷入测量陷阱。本文将揭示五个最具隐蔽性的操作…...
23种设计模式 - 组合模式(Composite)
组合模式(Composite)—— 文件夹套文件夹,统一操作 大白话解释 你的电脑里: 📄 文件(不能再包含东西)📁 文件夹(可以装文件,也可以装文件夹) &…...
微信聊天记录备份全攻略:从环境搭建到数据安全实战指南
微信聊天记录备份全攻略:从环境搭建到数据安全实战指南 【免费下载链接】WechatBakTool 基于C#的微信PC版聊天记录备份工具,提供图形界面,解密微信数据库并导出聊天记录。 项目地址: https://gitcode.com/gh_mirrors/we/WechatBakTool …...
Qt 5.12.8在Linux下编译qtvirtualkeyboard模块,我踩过的那些坑(附完整解决方案)
Qt 5.12.8在Linux下编译qtvirtualkeyboard模块的深度实践指南 当你在嵌入式或跨平台开发中突然发现系统自带的Qt缺少虚拟键盘模块时,那种感觉就像在沙漠里找到一瓶水却发现没带开瓶器。本文将带你深入探索在aarch64架构的Linux系统中,如何为预装的Qt 5.1…...
LCDWIKI SPI图形库:嵌入式TFT-LCD驱动核心架构与实战
1. LCDWIKI SPI 图形库深度解析:面向嵌入式显示驱动的底层架构与工程实践LCDWIKI SPI Library 是一款专为基于 SPI 接口的 TFT-LCD 显示模块设计的轻量级、高兼容性图形驱动核心库。它并非孤立的显示驱动,而是整个 LCDWIKI 显示生态系统的“基石类”&…...
