OpenCV从入门到精通实战(八)——基于dlib的人脸关键点定位
本文使用Python库dlib和OpenCV来实现面部特征点的检测和标注。
下面是代码的主要步骤和相关的代码片段:
步骤一:导入必要的库和设置参数
首先,代码导入了必要的Python库,并通过argparse设置了输入图像和面部标记预测器的参数。
from collections import OrderedDict
import numpy as np
import argparse
import dlib
import cv2
步骤二:定义面部关键点索引
使用OrderedDict定义了两组面部关键点,一组包含68个点,另一组包含5个点,这些关键点用于后续的特征提取。
FACIAL_LANDMARKS_68_IDXS = OrderedDict([("mouth", (48, 68)),("right_eyebrow", (17, 22)),("left_eyebrow", (22, 27)),("right_eye", (36, 42)),("left_eye", (42, 48)),("nose", (27, 36)),("jaw", (0, 17))
])
步骤三:人脸检测和关键点预测
使用dlib的面部检测器和预测器,对输入的图像进行人脸检测,并对每个检测到的人脸进行关键点定位。
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])
步骤四:关键点转换和可视化
将dlib的关键点数据结构转换为NumPy数组,然后通过自定义的visualize_facial_landmarks函数在图像上绘制关键点和凸包。
def shape_to_np(shape, dtype="int"):coords = np.zeros((shape.num_parts, 2), dtype=dtype)for i in range(0, shape.num_parts):coords[i] = (shape.part(i).x, shape.part(i).y)return coordsdef visualize_facial_landmarks(image, shape, colors=None, alpha=0.75):# 创建overlay, 绘制关键点和凸包
步骤五:处理每一个检测到的人脸
对于图像中每一个检测到的人脸,提取关键点,可视化,并显示每个部分的区域图像。
for (i, rect) in enumerate(rects):shape = predictor(gray, rect)shape = shape_to_np(shape)output = visualize_facial_landmarks(image, shape)cv2.imshow("Image", output)cv2.waitKey(0)
本文使用dlib和OpenCV对人脸图像进行关键点检测,并将检测到的关键点用于图像处理和分析。通过不同的面部部分的关键点,可以在应用程序中实现多种面部识别和分析功能。
#导入工具包
from collections import OrderedDict
import numpy as np
import argparse
import dlib
import cv2# 参数
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", default="shape_predictor_68_face_landmarks.dat",help="path to facial landmark predictor")
ap.add_argument("-i", "--image", default="images/liudehua2.jpg",help="path to input image")
args = vars(ap.parse_args())FACIAL_LANDMARKS_68_IDXS = OrderedDict([("mouth", (48, 68)),("right_eyebrow", (17, 22)),("left_eyebrow", (22, 27)),("right_eye", (36, 42)),("left_eye", (42, 48)),("nose", (27, 36)),("jaw", (0, 17))
])FACIAL_LANDMARKS_5_IDXS = OrderedDict([("right_eye", (2, 3)),("left_eye", (0, 1)),("nose", (4))
])def shape_to_np(shape, dtype="int"):# 创建68*2coords = np.zeros((shape.num_parts, 2), dtype=dtype)# 遍历每一个关键点# 得到坐标for i in range(0, shape.num_parts):coords[i] = (shape.part(i).x, shape.part(i).y)return coordsdef visualize_facial_landmarks(image, shape, colors=None, alpha=0.75):# 创建两个copy# overlay and one for the final output imageoverlay = image.copy()output = image.copy()# 设置一些颜色区域if colors is None:colors = [(19, 199, 109), (79, 76, 240), (230, 159, 23),(168, 100, 168), (158, 163, 32),(163, 38, 32), (180, 42, 220)]# 遍历每一个区域for (i, name) in enumerate(FACIAL_LANDMARKS_68_IDXS.keys()):# 得到每一个点的坐标(j, k) = FACIAL_LANDMARKS_68_IDXS[name]pts = shape[j:k]# 检查位置if name == "jaw":# 用线条连起来for l in range(1, len(pts)):ptA = tuple(pts[l - 1])ptB = tuple(pts[l])cv2.line(overlay, ptA, ptB, colors[i], 2)# 计算凸包else:hull = cv2.convexHull(pts)cv2.drawContours(overlay, [hull], -1, colors[i], -1)# 叠加在原图上,可以指定比例cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, output)return output# 加载人脸检测与关键点定位
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])# 读取输入数据,预处理
image = cv2.imread(args["image"])
(h, w) = image.shape[:2]
width=500
r = width / float(w)
dim = (width, int(h * r))
image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 人脸检测
rects = detector(gray, 1)# 遍历检测到的框
for (i, rect) in enumerate(rects):# 对人脸框进行关键点定位# 转换成ndarrayshape = predictor(gray, rect)shape = shape_to_np(shape)# 遍历每一个部分for (name, (i, j)) in FACIAL_LANDMARKS_68_IDXS.items():clone = image.copy()cv2.putText(clone, name, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,0.7, (0, 0, 255), 2)# 根据位置画点for (x, y) in shape[i:j]:cv2.circle(clone, (x, y), 3, (0, 0, 255), -1)# 提取ROI区域(x, y, w, h) = cv2.boundingRect(np.array([shape[i:j]]))roi = image[y:y + h, x:x + w](h, w) = roi.shape[:2]width=250r = width / float(w)dim = (width, int(h * r))roi = cv2.resize(roi, dim, interpolation=cv2.INTER_AREA)# 显示每一部分cv2.imshow("ROI", roi)cv2.imshow("Image", clone)cv2.waitKey(0)# 展示所有区域output = visualize_facial_landmarks(image, shape)cv2.imshow("Image", output)cv2.waitKey(0)





相关文章:
OpenCV从入门到精通实战(八)——基于dlib的人脸关键点定位
本文使用Python库dlib和OpenCV来实现面部特征点的检测和标注。 下面是代码的主要步骤和相关的代码片段: 步骤一:导入必要的库和设置参数 首先,代码导入了必要的Python库,并通过argparse设置了输入图像和面部标记预测器的参数。…...
unity | 动画模块之卡片堆叠切换
一、预览动画 可以放很多图,可以自己往后加,可以调图片x轴和y轴间距,可以调图片飞出方向,可以调堆叠方向。 图1 图片堆叠动画预览 二、纯净代码 有粉丝问我这个效果,最近很忙,没有时间细写,先…...
前端开发工程师需要学什么?
前端开发工程师需要学习的主要内容包括HTML、CSS、JavaScript、前端框架、响应式设计、性能优化、版本控制等。 HTML/CSS/JavaScript HTML:是网页的骨架,负责网页的结构和内容。CSS:用于美化网页,设计样式和布局。…...
网络常见命令
一.添加ip地址 (1)先进入端口号 interface 端口号 (2)添加ip地址 IP address xxx.xxx.x.x 主机位 二、查看路由表(查看192.168.3.1) display ip routing-table 192.168.3.1 三、宣告(宣告完后…...
logminer挖掘日志归档查找问题
--根据发生问题时间点查找归档文件 select first_time,NAME from gv$archived_log where first_time>2016-03-15 17:00:00 and first_time<2016-03-15 21:00:00; 2016-03-15 17:23:55 ARCH/jxdb/archivelog/2016_03_15/thread_1_seq_41588.4060.906577337 2016-03-15 17:…...
Flume和kafka的整合:使用Flume将日志数据抽取到Kafka中
文章目录 1、Kafka作为Source【数据进入到kafka中,抽取出来】2、kafka作为Sink 【数据从别的地方抽取到kafka里面】 1、Kafka作为Source【数据进入到kafka中,抽取出来】 kafka源 --> memory --> 控制台: a1.sources r1 a1.sinks k1…...
springboot实战(19)(条件分页查询、PageHelper、MYBATIS动态SQL、mapper映射配置文件、自定义类封装分页查询数据集)
引言: 该类博客的学习是基于b站黑马视频springbootvue视频学习!具体围绕项目——"大事件"进行实战学习。 目录 一、功能介绍(需求)。 1、文章列表功能基本介绍。 2、条件分页查询功能与注意。 3、前端页面效果。&#x…...
ScreenshotToCode安装教程
网页截图生成代码,我测试的效果一般 快速安装教程如下 1,首先你得有OpenAI的账号 国内用这个代理就可以: https://www.closeai-asia.com/ 充值一块钱,在本项目中可以生成两次 2,下载程序 下载程序压缩包࿱…...
最佳实践:如何在 Vue.js 项目中使用 Jest 进行单元测试
前言 随着应用程序规模和复杂性的增加,保证代码质量和稳定性变得愈发重要。单元测试作为软件测试的一部分,能够有效地捕捉代码中的错误,防止在开发过程中引入新的 Bug。在众多测试框架中,Jest 因其易用性、强大功能以及与 Vue.js…...
MySQL 与 MongoDB 存储差异分析
MySQL 与 MongoDB 存储差异分析:为什么随机生成数据的存储空间不同? 在实际应用中,我们常常需要选择合适的数据库系统来处理不同类型的数据。在这个过程中,数据库的 存储机制 和 性能优化 起着至关重要的作用。对于很多开发者来说…...
【2024】前端学习笔记19-ref和reactive使用
学习笔记 1.ref2.reactive3.总结 1.ref ref是 Vue 3 中用来创建响应式引用的一个函数,通常用于基本数据类型(如字符串、数字、布尔值等)或对象/数组的单一值。 ref特点: ref 可以用来创建单个响应式对象对于 ref 包裹的值&…...
2024.11.26总结
今晚考了个科目四,只准备了半天,考试的时候几乎都是乱选的,选完后就走人了,相当于白白浪费了一次机会。有时候感觉上班太累了,不知道是心累,还是其他方面。 思来想去,还是决定继续在CSDN上输出…...
《通俗易懂 · JSqlParser 解析和构造SQL》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流…...
OSPTrack:一个包含多个生态系统中软件包执行时生成的静态和动态特征的标记数据集,用于识别开源软件中的恶意行为。
2024-11-22 ,由格拉斯哥大学创建的OSPTrack数据集,目的是通过捕获在隔离环境中执行包和库时生成的特征,包括静态和动态特征,来识别开源软件(OSS)中的恶意指标,特别是在源代码访问受限时…...
路由器中继与桥接
一 . 背景 现在的路由器大多数已经开始支持多种网络连接模式,以下将以TP-Link迷你无线路由器为例进行展开介绍。在TP-Link迷你无线路由器上一般有AP(接入点)模式,Router(无线路由)模式,Repeate…...
香橙派--安装RKMPP、x264、libdrm、FFmpeg(支持rkmpp)以及opencv(支持带rkmpp的ffmpeg)(适用于RK3588平台)
1. 安装RKMPP git clone https://github.com/rockchip-linux/mppcd mpp/build/linux/aarch64./make-Makefiles.bashmake -j8sudo make installRKMPP:用于编解码测试,支持RK3588平台。 2. 安装x264 git clone https://code.videolan.org/videolan/x264…...
【spark-spring boot】学习笔记
目录 说明RDD学习RDD介绍RDD案例基于集合创建RDDRDD存入外部文件中 转换算子 操作map 操作说明案例 flatMap操作说明案例 filter 操作说明案例 groupBy 操作说明案例 distinct 操作说明案例 sortBy 操作说明案例 mapToPair 操作说明案例 mapValues操作说明案例 groupByKey操作说…...
【Python】九大经典排序算法:从入门到精通的详解(冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、计数排序、基数排序、桶排序)
文章目录 1. 冒泡排序(Bubble Sort)2. 选择排序(Selection Sort)3. 插入排序(Insertion Sort)4. 归并排序(Merge Sort)5. 快速排序(Quick Sort)6. 堆排序&…...
【346】Postgres内核 Startup Process 通过 signal 与 postmaster 交互实现 (5)
1. Startup Process 进程 postmaster 初始化过程中, 在进入 ServerLoop() 函数之前,会先通过调用 StartChildProcess() 函数来开启辅助进程,这些进程的目的主要用来完成数据库的 XLOG 相关处理。 如: 核实 pg_wal 和 pg_wal/archive_status 文件是否存在Postgres先前是否发…...
Jmeter中的测试片段和非测试原件
1)测试片段 1--测试片段 功能特点 重用性:将常用的测试元素组合成一个测试片段,便于在多个线程组中重用。模块化:提高测试计划的模块化程度,使测试计划更易于管理和维护。灵活性:可以通过模块控制器灵活地…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...
DeepSeek越强,Kimi越慌?
被DeepSeek吊打的Kimi,还有多少人在用? 去年,月之暗面创始人杨植麟别提有多风光了。90后清华学霸,国产大模型六小虎之一,手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水,单月光是投流就花费2个亿。 疯…...
