基于RV1126开发板的人脸姿态估计算法开发
1. 人脸姿态估计简介
人脸姿态估计是通过对一张人脸图像进行分析,获得脸部朝向的角度信息。姿态估计是多姿态问题中较为关键的步骤。一般可以用旋转矩阵、旋转向量、四元数或欧拉角表示。人脸的姿态变化通常包括上下俯仰(pitch)、左右旋转(yaw)以及平面内角度旋转(roll)。因此,姿态估计在多姿态人脸的识别和司机行为检测等应用场景,具有巨大的现实意义和实用价值。
基于EASY-EAI-Nano硬件主板的运行效率:
| 算法种类 | 运行效率 |
| face_pose_estimation | 22ms |
2. 快速上手
2.1 开发环境准备
如果您初次阅读此文档,请阅读《入门指南/开发环境准备/Easy-Eai编译环境准备与更新》,并按照其相关的操作,进行编译环境的部署。
在PC端Ubuntu系统中执行run脚本,进入EASY-EAI编译环境,具体如下所示。
cd ~/develop_environment
./run.sh

2.2 源码下载以及例程编译
在EASY-EAI编译环境下创建存放源码仓库的管理目录:
cd /opt
mkdir EASY-EAI-Toolkit
cd EASY-EAI-Toolkit
通过git工具,在管理目录内克隆远程仓库
git clone https://github.com/EASY-EAI/EASY-EAI-Toolkit-C-Demo.git

注:
* 此处可能会因网络原因造成卡顿,请耐心等待。
* 如果实在要在gitHub网页上下载,也要把整个仓库下载下来,不能单独下载本实例对应的目录。
进入到对应的例程目录执行编译操作,具体命令如下所示:
cd EASY-EAI-Toolkit-C-Demo/algorithm-face_pose_estimation/
./build.sh cpres
注:
* 若build.sh脚本带有cpres参数,则会把Release/目录下的所有资源都拷贝到开发板上。
* 若build.sh脚本不带任何参数,则仅会拷贝demo编译出来的可执行文件。
* 由于依赖库部署在板卡上,因此交叉编译过程中必须保持adb连接。

2.3 模型部署
要完成算法Demo的执行,需要先下载人脸检测算法模型。
百度网盘链接为:https://pan.baidu.com/s/1cxnx1T0ldJvoqkyTk1RmUg(提取码:0b6h )。

同时也要下载人员姿态估计算法模型。
百度网盘链接为:https://pan.baidu.com/s/1sNZb2X0I7TwdM_n89HI9gg (提取码:j19k )。

然后需要把下载的人脸检测模型和人脸姿态估计算法模型复制粘贴到Release/目录:

再通过下方命令将模型署到板卡中,如下所示。
cp ./Release/*.model /mnt/userdata/Demo
2.4 例程运行
通过按键Ctrl+Shift+T创建一个新窗口,执行adb shell命令,进入板卡运行环境。
adb shell

进入板卡后,定位到例程上传的位置,如下所示:
cd /userdata/Demo
运行例程命令如下所示:
./test-face-pose-estimation test-1.jpg
2.5 运行效果
face-pose-estimation的Demo执行效果如下所示:

再开一个窗口,在PC端Ubuntu环境通过以下命令可以把图片拉回来:
adb pull /userdata/Demo/result.jpg .
结果图片如下所示:

API的详细说明,以及API的调用(本例程源码),详细信息见下方说明。
3. 人脸检测API说明
3.1 引用方式
为方便客户在本地工程中直接调用我们的EASY EAI api库,此处列出工程中需要链接的库以及头文件等,方便用户直接添加。
| 选项 | 描述 |
| 头文件目录 | easyeai-api/algorithm_api/face_detect |
| 库文件目录 | easyeai-api/algorithm_api/face_detect |
| 库链接参数 | -lpthread -lface_detect -lrknn_api |
3.2 人脸检测初始化函数
设置人脸检测初始化函数原型如下所示。
int face_detect_init(rknn_context *ctx, const char *path)
具体介绍如下所示。
| 函数名: face_detect_init() | |
| 头文件 | face_detect.h |
| 输入参数 | ctx:rknn_context句柄 |
| path:算法模型的路径 | |
| 返回值 | 成功返回:0 |
| 失败返回:-1 | |
| 注意事项 | 无 |
3.3 人脸检测运行函数
设face_detect_run原型如下所示。
int face_detect_run(rknn_context ctx, cv::Mat &input_image, std::vector<det> &result)
具体介绍如下所示。
| 函数名: face_detect_run () | |
| 头文件 | face_detect.h |
| 输入参数 | ctx: rknn_context句柄 |
| input_image:Opencv Mat格式图像 | |
| result:人脸检测的结果输出 | |
| 返回值 | 成功返回:0 |
| 失败返回:-1 | |
| 注意事项 | 无 |
3.4 人脸检测释放函数
人脸检测释放函数原型如下所示。
int face_detect_release(rknn_context ctx)
具体介绍如下所示。
| 函数名: face_detect_release () | |
| 头文件 | face_detect.h |
| 输入参数 | ctx: rknn_context句柄 |
| 返回值 | 成功返回:0 |
| 失败返回:-1 | |
| 注意事项 | 无 |
4. 人脸姿态估计API说明
4.1 引用方式
为方便客户在本地工程中直接调用我们的EASY EAI api库,此处列出工程中需要链接的库以及头文件等,方便用户直接添加。
| 选项 | 描述 |
| 头文件目录 | easyeai-api/algorithm_api/face_pose_estimation |
| 库文件目录 | easyeai-api/algorithm_api/face_pose_estimation |
| 库链接参数 | -lpthread -lface_pose_estimation -lrknn_api |
4.2 人脸姿态初始化函数
设置人脸检测初始化函数原型如下所示。
int face_pose_estimation_init(rknn_context *ctx, const char * path)
具体介绍如下所示。
| 函数名: face_pose_estimation_init() | |
| 头文件 | face_pose_estimation.h |
| 输入参数 | ctx:rknn_context句柄 |
| path:算法模型的路径 | |
| 返回值 | 成功返回:0 |
| 失败返回:-1 | |
| 注意事项 | 无 |
4.3 人脸姿态执行函数
设face_pose_estimation_run原型如下所示。
int face_pose_estimation_run(rknn_context ctx, cv::Mat *face_image, float *result)
具体介绍如下所示。
| 函数名: face_pose_estimation_run () | |
| 头文件 | face_pose_estimation.h |
| 输入参数 | ctx: rknn_context句柄 |
| face_image: 图像数据输入(cv::Mat是Opencv的类型) | |
| result: yaw(偏航角), pitch(俯仰角), roll(翻滚角) | |
| 返回值 | 成功返回:0 |
| 失败返回:-1 | |
| 注意事项 | 无 |
4.4 人脸姿态释放函数
人脸检测释放函数原型如下所示。
int face_pose_estimation_release(rknn_context ctx)
具体介绍如下所示。
| 函数名: face_pose_estimation_release () | |
| 头文件 | face_pose_estimation.h |
| 输入参数 | ctx: rknn_context句柄 |
| 返回值 | 成功返回:0 |
| 失败返回:-1 | |
| 注意事项 | 无 |
5. 人脸姿态估计算法例程
例程目录为Toolkit-C-Demo/algorithm-face_pose_estimation/test-face-pose-estimation.cpp,操作流程如下。

参考例程如下所示。
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <fstream>
#include <atomic>
#include <queue>
#include <thread>
#include <mutex>
#include <chrono>
#include <sys/time.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <opencv2/opencv.hpp>
#include <unistd.h>
#include <sys/syscall.h>#include "face_detect.h"
#include "face_alignment.h"
#include "face_pose_estimation.h"using namespace std;
using namespace cv;int plot_one_box(Mat src, int x1, int x2, int y1, int y2, char *label, char colour)
{int tl = round(0.002 * (src.rows + src.cols) / 2) + 1;rectangle(src, cv::Point(x1, y1), cv::Point(x2, y2), Scalar(255, 0, 0, 255), 3);int tf = max(tl -1, 1);int base_line = 0;cv::Size t_size = getTextSize(label, FONT_HERSHEY_SIMPLEX, (float)tl/3, tf, &base_line);int x3 = x1 + t_size.width;int y3 = y1 - t_size.height - 3;rectangle(src, cv::Point(x1, y1), cv::Point(x3, y3), Scalar(255, 0, 0, 255), -1);putText(src, label, cv::Point(x1, y1 - 2), FONT_HERSHEY_SIMPLEX, (float)tl/3, cv::Scalar(255, 255, 255, 255), tf, 8);return 0;
}int main(int argc, char **argv)
{if( argc != 2){printf("./test-face-pose-estimation xxx.jpg \n");return -1;}rknn_context detect_ctx, face_pose_estimation_ctx;std::vector<det> detect_result;int ret;cv::Mat src;src = cv::imread(argv[1], 1);/* 人脸检测初始化 */ret = face_detect_init(&detect_ctx, "./face_detect.model");if( ret < 0){printf("face_detect_init fail! ret=%d\n", ret);return -1;}/* 人脸姿态估计初始化 */ret = face_pose_estimation_init(&face_pose_estimation_ctx, "./face_pose_estimation.model");if( ret < 0){printf("face_pose_estimation_init fail! ret=%d\n", ret);return -1;}/* 人脸检测执行 */face_detect_run(detect_ctx, src, detect_result);for( int i=0; i < (int)detect_result.size() ; i++ ){int x = (int)(detect_result[i].box.x);int y = (int)(detect_result[i].box.y);int w = (int)(detect_result[i].box.width);int h = (int)(detect_result[i].box.height);int max = (w > h)?w:h;// 判断图像裁剪是否越界if( ((x +max) > src.cols) || ((y +max) > src.rows) ){continue;}cv::Mat roi_img, reize_img, reize_img_rgb;roi_img = src(cv::Rect(x, y, max,max));roi_img = roi_img.clone();resize(roi_img, reize_img, Size(224,224), 0, 0, INTER_AREA);cvtColor(reize_img, reize_img_rgb, COLOR_BGR2RGB);/* 人脸姿态估计运行 */float pose_result[3];face_pose_estimation_run(face_pose_estimation_ctx, &reize_img_rgb, pose_result);printf("yaw(偏航角):%f, pitch(俯仰角):%f, roll(翻滚角):%f\n", pose_result[0], pose_result[1], pose_result[2]);char label_text[100];memset(label_text, 0 , sizeof(label_text));sprintf(label_text, "yaw:%0.2f pitch:%0.2f roll:%0.2f", pose_result[0], pose_result[1], pose_result[2]); plot_one_box(src, x, x+w, y, y+h, label_text, i%10);}imwrite("result.jpg", src);/* 人脸检测释放 */face_detect_release(detect_ctx);/* 人脸姿态估计释放 */face_pose_estimation_release(face_pose_estimation_ctx);return 0;
}
相关文章:
基于RV1126开发板的人脸姿态估计算法开发
1. 人脸姿态估计简介 人脸姿态估计是通过对一张人脸图像进行分析,获得脸部朝向的角度信息。姿态估计是多姿态问题中较为关键的步骤。一般可以用旋转矩阵、旋转向量、四元数或欧拉角表示。人脸的姿态变化通常包括上下俯仰(pitch)、左右旋转(yaw)以及平面内角度旋转(r…...
鲲鹏+昇腾部署集群管理软件GPUStack,两台服务器搭建双节点集群【实战详细踩坑篇】
前期说明 配置:2台鲲鹏32C2 2Atlas300I duo,之前看网上文档,目前GPUstack只支持910B芯片,想尝试一下能不能310P也部署试试,毕竟华为的集群软件要收费。 系统:openEuler22.03-LTS 驱动:24.1.rc…...
【C#】CAN通信的使用
在C#中实现CAN通信通常需要借助第三方库或硬件设备的驱动程序,因为C#本身并没有直接内置支持CAN通信的功能。以下是一个关于如何使用C#实现CAN通信的基本指南,包括所需的步骤和常用工具。 1. 硬件准备 要进行CAN通信,首先需要一个支持CAN协…...
火山引擎旗下的产品
用户问的是火山引擎旗下的产品,我需要详细列出各个类别下的产品。首先,我得确认火山引擎有哪些主要业务领域,比如云计算、大数据、人工智能这些。然后,每个领域下具体有哪些产品呢?比如云计算方面可能有云服务器、容器…...
Elasticsearch 故障转移及水平扩容
一、故障转移 Elasticsearch 的故障转移(Failover)机制是其高可用性的核心,通过分布式设计、自动检测和恢复策略确保集群在节点故障时持续服务。 1.1 故障转移的核心组件 组件作用Master 节点管理集群状态(分片分配、索引创建&…...
机器学习中 提到的张量是什么?
在机器学习中, 张量(Tensor) 是一个核心数学概念,用于表示和操作多维数据。以下是关于张量的详细解析: 一、数学定义与本质 张量在数学和物理学中的定义具有多重视角: 多维数组视角 传统数学和物理学中,张量被定义为多维数组,其分量在坐标变换时遵循协变或逆变规则。例…...
edge 更新到135后,Clash 打开后,正常网页也会自动跳转
发现了一个有意思的问题:edge 更新135后,以前正常使用的clash出现了打开deepseek也会自动跳转: Search Resultshttps://zurefy.com/zu1.php#gsc.tab0&gsc.qdeepseek ,也就是不需要梯子的网站打不开了,需要的一直正…...
prime 1 靶场笔记(渗透测试)
环境说明: 靶机prime1和kali都使用的是NAT模式,网段在192.168.144.0/24。 Download (Mirror): https://download.vulnhub.com/prime/Prime_Series_Level-1.rar 一.信息收集 1.主机探测: 使用nmap进行全面扫描扫描,找到目标地址及…...
实验一 字符串匹配实验
一、实验目的 1.熟悉汇编语言编程环境和DEBUG调试程序的使用。 2.掌握键盘输入字符串的方法和分支程序的设计。 二、实验内容 编程实现:从键盘分别输入两个字符串,然后进行比较,若两个字符串的长度…...
跨境电商中的几种支付方式——T/T、L/C、D/P、D/A、O/A
在进行跨境电商的B端系统设计时,需要考虑的关键方面之一是支付流程。它为交易的成功奠定了基础,并确保涉及的双方都受到保护。 在本文中,我们将深入探讨各种常见支付方式的复杂性,包括电汇 (T/T)、信用证 (L/C)、付款交单 (D/P)、…...
第16届蓝桥杯单片机模拟试题Ⅲ
试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //sys.c extern unsigned char UI; //界面标志(0湿度界面、1参数界面、2时间界面) extern unsigned char time; //时间间隔(1s~10S) extern bit ssflag; //启动/停止标志…...
打造现代数据基础架构:MinIO对象存储完全指南
目录 打造现代数据基础架构:MinIO对象存储完全指南1. MinIO介绍1.1 什么是对象存储?1.2 MinIO核心特点1.3 MinIO使用场景 2. MinIO部署方案对比2.1 单节点单驱动器(SNSD/Standalone)2.2 单节点多驱动器(SNMD/Standalone Multi-Drive)2.3 多节点多驱动器(…...
OOM问题排查和解决
问题 java.lang.OutOfMemoryError: Java heap space 排查 排查手段 jmap命令 jmap -dump,formatb,file<file-path> <pid> 比如 jmap -dump:formatb,file./heap.hprof 44532 使用JVisualVM工具: JVisualVM是一个图形界面工具,它可以帮…...
OSI 七层模型与 TCP/IP 协议栈详解
OSI 七层模型与 TCP/IP 协议栈详解 网络协议模型是理解计算机网络和通信的基础,而 OSI 七层模型和 TCP/IP 协议栈是最常见的两种网络通信模型。虽然这两者有些不同,但它们都提供了一种分层的结构,帮助我们理解和设计网络通信。本文将详细介绍…...
「出海匠」借助CloudPilot AI实现AWS降本60%,支撑AI电商高速增长
🔎公司简介 「出海匠」(chuhaijiang.com)是「数绘星云」公司打造的社交内容电商服务平台,专注于为跨境生态参与者提供数据支持与智能化工作流。平台基于大数据与 AI 技术,帮助商家精准分析市场趋势、优化运营策略&…...
LeetCode[541]反转字符串Ⅱ
思路: 题目给我们加了几个规则,剩余长度小于2k,大于等于k就反转k个,小于k就全部反转,我们按照这个逻辑来就行。 第一就是大于等于k就反转k个,我们for循环肯定是i2k了,接下来就是判断是否大于等于…...
队列的各种操作实现(数据结构C语言多文件编写)
1.先创建queue.h声明文件(Linux命令:touch queue.h)。编写函数声明如下(打开文件 Linux 操作命令:vim queue.h): //头文件 #ifndef __QUEUE_H__ #define __QUEUE_H__ //队列 typedef struct queue{int* arr;int in;int out;int cap;int size; }queue_t;…...
# Unity动画控制核心:Animator状态机与C#脚本实战指南 (Day 29)
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
C++中extern关键字
C中extern关键字的完整用法总结 extern是C中管理链接性(linkage)的重要关键字,主要用于声明外部定义的变量或函数。以下是详细的用法分类和完整示例: 一、基本用法 1. 声明外部全局变量 // globals.cpp int g_globalVar 42; …...
【Python爬虫】简单案例介绍3
本文继续接着我的上一篇博客【Python爬虫】简单案例介绍2-CSDN博客 目录 3.3 代码开发 3.3 代码开发 编写代码的步骤: request请求科普中国网站地址url,解析得到类名为"list-block"的div标签。 for循环遍历这个div列表里的每个div࿰…...
计算机视觉与深度学习 | 视觉里程计(Visual Odometry, VO)学习思路总结
视觉里程计(Visual Odometry, VO)学习思路总结 视觉里程计(VO)是通过摄像头捕获的图像序列估计相机运动轨迹的技术,广泛应用于机器人、自动驾驶和增强现实等领域。以下是一个系统的学习路径,涵盖基础理论、核心算法、工具及实践建议:一、基础理论与数学准备 核心数学工具…...
android面试情景题详解:android如何处理断网、网络切换或低速网络情况下的业务连续性
在移动互联网时代,Android应用已经成为人们日常生活中不可或缺的一部分。从社交媒体到在线购物,从移动办公到娱乐消费,几乎所有的服务都依赖于网络连接。然而,网络环境并非总是稳定可靠。断网、网络切换(如从Wi-Fi切换…...
swift菜鸟教程6-10(运算符,条件,循环,字符串,字符)
一个朴实无华的目录 今日学习内容:1.Swift 运算符算术运算符比较运算符逻辑运算符位运算符赋值运算区间运算符其他运算符 2.Swift 条件语句3.Swift 循环4.Swift 字符串字符串属性 isEmpty字符串常量let 变量var字符串中插入值字符串连接字符串长度 String.count使用…...
质变科技发布自主数据分析MCP Server
2025年4月9日,质变科技正式发布Relyt AI MCP(Model Context Protocol),结合Relyt AI 在自主数据分析领域的前沿积累与MCP的开放连接能力,我们为用户带来了一个更智能、更灵活的数据交互生态系统。这一发布不仅拓展了Re…...
如何通过技术手段降低开发成本
通过技术手段降低开发成本的关键在于: 自动化工具的使用、优化开发流程、云计算资源的利用、开发技术栈的精简与创新、团队协作平台的高效管理。 其中,自动化工具的使用是最为有效的技术手段之一。自动化工具通过减少人工干预和重复性工作,大…...
Ubuntu上docker、docker-compose的安装
今天来实践下Ubuntu上面安装docker跟docker-compose,为后面安装dify、fastgpt做准备。 一、安装docker sudo apt-get updatesudo apt-get install docker.io 然后系统输入 docker --version 出现下图即为docker安装成功。 二、安装docker-compose 我先看下系统…...
CSS 列表样式学习笔记
CSS 列表样式提供了强大的功能,用于定制 HTML 列表的外观。通过 CSS,可以轻松地改变列表项的标记类型、位置,甚至使用图像作为列表项标记。以下是对 CSS 列表样式的详细学习笔记。 一、HTML 列表类型 在 HTML 中,主要有两种类型…...
AI云游戏盒子:未来娱乐的新纪元
AI云游戏盒子:未来娱乐的新纪元 随着科技的不断进步,人工智能(AI)与云计算技术的结合正在重新定义我们享受数字娱乐的方式。2025年,一款名为“AI云游戏盒子”的产品正逐渐成为家庭娱乐的核心设备,它不仅集…...
OpenCV图像处理进阶教程:几何变换与频域分析全解析
OpenCV图像处理进阶教程:几何变换与频域分析全解析 📚 本文提供了OpenCV图像处理的核心操作详解,从基础的几何变换到高级的频域分析,代码示例清晰易懂,实用性强。完整代码已开源至GitHub:https://github.co…...
AJAX与Axios基础
目录 一、AJAX 核心概念解析 1.1 AJAX 的核心概念 1.2 AJAX 工作原理 1.3 AJAX 局限性 二、axios 库介绍 2.1 Axios 核心特性 2.2 快速上手 2.3 核心配置项 2.4 错误处理标准方案 三、Axios 核心配置项 3.1 常用核心配置项 1. url 2. method 3. params 4. data …...
