头部姿态估计代码+教程

news2024/9/21 0:53:19

前言

在这里插入图片描述

  • 头部姿态估计是计算机视觉中的一个具有挑战性的问题,因为它需要完成多个步骤。
  • 首先,我们需要在画面中定位人脸,然后识别出各种面部特征点。
  • 如今,当人脸正对摄像头时,识别人脸似乎是一个简单的任务。但问题在于,当人脸处于某个角度时,由于头部的移动,某些面部特征点可能不可见。
  • 接下来,我们需要将这些点转换成三维坐标来计算倾斜角度。听起来工作量很大?别担心,我们会一步步来,并参考两个非常棒的资源,这将使我们的工作变得容易得多。

目录

  • 要求
  • 人脸检测
  • 面部特征点检测
  • 姿态估计

要求
对于这个项目,我们需要OpenCV和TensorFlow,让我们安装它们吧。

使用pip

pip install opencv-python
pip install tensorflow

使用conda

conda install -c conda-forge opencv
conda install -c conda-forge tensorflow

人脸检测

我们的第一步是在图像上找到人脸,以便我们可以在上面找到面部特征点。为此,我们将使用OpenCV DNN模块的一个Caffe模型。如果你想知道它与其他模型(如Haar级联或Dlib的正面人脸检测器)相比如何,或者你想深入了解它,可以参阅这篇文章:

import cv2
import numpy as np
modelFile = "models/res10_300x300_ssd_iter_140000.caffemodel"
configFile = "models/deploy.prototxt.txt"
net = cv2.dnn.readNetFromCaffe(configFile, modelFile)
img = cv2.imread('test.jpg')
h, w = img.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(img, (300, 300)), 1.0,
(300, 300), (104.0, 117.0, 123.0))
net.setInput(blob)
faces = net.forward()
# 在图片上绘制人脸框
for i in range(faces.shape[2]):
    confidence = faces[0, 0, i, 2]
    if confidence > 0.5:
        box = faces[0, 0, i, 3:7] * np.array([w, h, w, h])
        (x, y, x1, y1) = box.astype("int")
        cv2.rectangle(img, (x, y), (x1, y1), (0, 0, 255), 2)

加载网络使用cv2.dnn.readNetFromCaffe并传递模型层和权重作为参数。它在调整为300x300大小的图像上表现最好。

面部特征点检测

最常用的可能是Dlib的面部特征点检测,它可以提供68个特征点,但准确性不高。相反,我们将使用Yin Guobing在GitHub仓库提供的面部特征点检测器。它同样提供了68个特征点,并且是一个基于TensorFlow的CNN,在五个数据集上训练!预训练模型可在此处找到。作者撰写了一系列文章解释了包括背景、数据集、预处理、模型架构、训练和部署等内容,这里强烈推荐你阅读。

在这一系列的第一篇文章中,他描述了视频中面部特征点稳定性的问题,并介绍了现有的解决方案,如OpenFace和Dlib的面部特征点检测,以及可用的数据集。第三篇文章全是关于数据预处理和使其准备好使用。接下来的两篇文章的工作是提取面部并应用面部特征点以准备训练CNN,并将它们存储为TFRecord文件。第六篇文章使用TensorFlow训练了一个模型。在这篇文章中,我们可以看到损失函数在训练中的重要性,因为最初他使用了tf.losses.mean_pairwise_squared_error,它基于点之间的关系进行优化以最小化损失,但无法很好地泛化。相比之下,使用tf.losses.mean_squared_error时效果很好。在最后一篇文章中,模型被导出为API,并展示了如何在Python中使用它。
在这里插入图片描述

该模型接受包含脸部的128x128大小的方框,并返回68个面部特征点。下面提供的代码来自此处,也可以用来在其上绘制3D注释框。代码经过修改,可以在所有脸上绘制面部特征点,而不仅仅是原始代码中的一个。

这段代码将在脸上绘制面部特征点。

绘制面部特征点

使用draw_annotation_box()函数,我们还可以如下所示绘制注释框。
在这里插入图片描述

带有注释框

姿态估计

这是Learn OpenCV上的一篇好文章,它解释了如何在图像上进行头部姿态检测,并详细说明了将点转换到三维空间以及使用cv2.solvePnP来寻找旋转和平移向量的数学原理。快速浏览那篇文章将有助于理解其内在运作,因此我在这里只简要介绍。

我们需要脸部的六个点,即鼻尖、下巴、嘴唇左右极点以及左眼左角和右眼右角。我们取这些面部特征点的标准三维坐标,并尝试估计鼻尖处的旋转和平移向量。现在,为了准确估计,我们需要相机的固有参数,如焦距、光学中心和径向畸变参数。我们可以估算前两者,并假设后者不存在以简化工作。在获得所需向量后,我们可以将那些三维点投影到二维表面上,也就是我们的图像。

如果我们仅使用现有代码并找到与x轴的角度,我们可以得到如下结果。
在这里插入图片描述

结果

它非常适合记录头部上下移动,但不适用于左右移动。那么如何做到这一点呢?好吧,上面我们看到了脸部上的注释框。如果我们能够利用它来测量左右移动。
在这里插入图片描述

带有注释框

我们可以找到两条深蓝色线之间的中间线作为指针,并找到与y轴的角度来确定移动角度。
在这里插入图片描述

结果
结合这两者,我们可以得到我们想要的方向。完整的代码也可以在我的GitHub仓库中找到,还有其他用于在线监考解决方案的各种子模型。

在我测试i5处理器时,即使显示图像,我也能获得健康的每秒6.76帧的速度,而面部特征点检测模型只需要0.05秒就可以找到它们。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2150651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

个人为什么不能参与场外期权?也有办法可以开始交易!

今天带你了解个人为什么不能参与场外期权?也有办法可以开始交易!由于监管政策、风险管理、市场透明度和适合性等因素,个人投资者在中国市场上不能参与场外期权交易。 个人为什么不能参与场外期权? 在中国市场上,个人…

Web+Mysql——MyBatis

MyBatis 目标 能够完成Mybatis代理方式查询数据能够理解Mybatis核心配置文件的配置 1,Mybatis 1.1 Mybatis概述 1.1.1 Mybatis概念 MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发 MyBatis 本是 Apache 的一个开源项目iBatis, 2010年这个项目由…

Python 从入门到实战23(属性property)

我们的目标是:通过这一套资料学习下来,通过熟练掌握python基础,然后结合经典实例、实践相结合,使我们完全掌握python,并做到独立完成项目开发的能力。 上篇文章我们讨论了类的定义、使用方法的相关知识。今天我们将学…

【HTTP】请求“报头”(Host、Content-Length/Content-Type、User-Agent(简称 UA))

Host 表示服务器主机的地址和端口号 URL 里面不是已经有 Host 了吗,为什么还要写一次? 这里的 Host 和 URL 中的 IP 地址、端口什么的,绝大部分情况下是一样的,少数情况下可能不同当前我们经过某个代理进行转发。过程中&#xf…

【JAVA开源】基于Vue和SpringBoot的蜗牛兼职平台

本文项目编号 T 034 ,文末自助获取源码 \color{red}{T034,文末自助获取源码} T034,文末自助获取源码 目录 一、系统介绍1.1 平台架构1.2 管理后台1.3 用户网页端1.4 技术特点 二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景…

LinuxC高级作业2

1.整理思维导图 2.做一套笔试题 一: 1.cd .. mkdir dir1 cd dir1 touch file1 2.cp ~/mnt/dir1/ -r * ~/home/dir2/ 3.pwd 4.ls -l 5.ifconfig 6.top 10.find /usr -type f -name "*name*" 11.:wq 13.df -h 14.tar -xzvf tmp.tar.gz 15.sudo c…

我的数据库旅程:从迷茫到觉醒

我的数据库旅程:从迷茫到觉醒 《中国数据库前世今生》纪录片的上线,使我回顾了中国数据库技术的演进历程,也联想到了自己在这一领域的工作经历。数据库技术从80年代在中国的初步应用到如今蓬勃发展,贯穿了整个信息化进程。作为一名…

【Qt之·文件操作·类QTextStream、QDataStream】

系列文章目录 文章目录 前言一、概述1.1 QTextStream类1.2 QTextStream类的作用和用途 二、基本用法2.1 QTextStream成员函数2.2 QTextStream格式描述符、描述符方法2.3 QDataStream成员函数2.4 创建QTextStream对象并关联输入/输出设备(如文件、标准输入/输出流等&…

EPSILON环境配置和本地测试

文章目录 一、环境配置1.1 拉取镜像构建容器1.2 在容器中安装常用的包1.3 安装依赖1.4 安装OOQP1.4.1 安装blas1.4.2 安装ma271.4.3 安装OOQP 1.5 安装Protobuf 二、本地编译测试2.1 拉取源码并编译2.2 X11转发docker图形化界面2.3 测试一个小例子 三、镜像 一、环境配置 宿主…

Vue3:$attrs实现组件通信

目录 一.性质 1.响应式 2.包含所有非prop属性 3.动态属性 二.作用 1.访问非prop属性 2.灵活性 3.组件重用 三.使用 1.爷爷组件 2.父亲组件 3.儿子组件 四.代码 1.爷爷组件代码 2.父亲组件代码 3.孙子组件代码 五.效果图 在Vue 3中,$attrs 是一个响…

string类的模拟实现以及oj题

前言 上篇博客实现了string类的begin()、end()、构造函数、析构函数、c_str、size()、clear()、capacity()、[ ]、reserve()、push_back、append()、insert()、。这篇博客实现剩下的一些重要功能。 string类的模拟实现 string.h #include<iostream> #include<stri…

稳了,搭建Docker国内源图文教程

大家好&#xff0c;之前分享了我的开源作品 Cloudflare Workers Proxy&#xff0c;它的作用是代理被屏蔽的地址&#xff0c;理论上支持代理任何被屏蔽的域名&#xff0c;使用方式也很简单&#xff0c;只需要设置环境变量 PROXY_HOSTNAME 为被屏蔽的域名&#xff0c;最后通过你的…

强化信息安全:密码机密钥管理的策略与实践

强化信息安全&#xff1a;密码机密钥管理的策略与实践 随着信息技术的飞速发展&#xff0c;信息安全已成为企业和社会关注的焦点。密码机作为加密通信和数据保护的关键设备&#xff0c;其密钥管理直接关系到整个信息系统的安全性。本文旨在探讨密码机密钥管理的策略与实践&…

如何根据协议请求去捕捉在个文件中发出去的

场景&#xff1a;随着业务越来越复杂&#xff0c;一个“触发”可能发出去N个协议&#xff0c;此时有某一个协议发生了报错&#xff0c;需要去找这个协议&#xff0c;去文件中走读逻辑&#xff0c;去找该协议&#xff0c;效率很慢&#xff0c;业务极其复杂的情况下&#xff0c;很…

渐变色代码主题你受得了吗

分享一个vscode编辑器的渐变色主题 效果图如下 vscode扩展搜索 gradient theme安装即可。

毕业设计选题:基于springboot+vue+uniapp的驾校报名小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

二级C语言2023-9易错题

1 二叉树结点数计算&#xff1a; 一棵二叉树有10个度为1的结点&#xff0c;7个度为2的结点&#xff0c;则该二叉树共有____个结点。 解&#xff1a; 2 指针&#xff1a; 有以下程序 #inctude<stdio.h> #include<stdlib.h> main() { int *a&#xff0c;*b&…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【扩展组件】上

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 子系统开发内核 轻量系统内核&#xff08;LiteOS-M&#xff09; 轻量系统内核&#…

CSS01-语法规范、基础选择器

一、CSS语法规范 示例&#xff1a; 二、CSS的基础选择器 选择器(选择符)就是根据不同需求把不同的标签选出来这就是选择器的作用。 简单来说&#xff0c;就是选择标签用的。 选择器的分类&#xff1a; 1、标签选择器 2、类选择器&#xff08;开发最常用&#xff09; 长字符命名…

本地搭建我的世界服务器(JAVA)简单记录

网上参考教程挺多的&#xff0c;踩了不少坑&#xff0c;简单记录一下&#xff0c;我做的是一个私人服务器&#xff0c;就是和朋友3、4个人玩。 笨蛋 MC 开服教程 先放一个比较系统和完整的教程&#xff0c;萌新可用&#xff0c;这个教程很详细&#xff0c;我只是记录一下自己的…