人脸识别Adaface之libpytorch部署
目录
- 1. libpytorch下载
- 2. Adaface模型下载
- 3. 模型转换
- 4. c++推理
- 4.1 前处理
- 4.2 推理
- 4.3 编译运行
- 4.3.1 写CMakeLists.txt
- 4.3.2 编译
- 4.3.3 运行
1. libpytorch下载
参考:
https://blog.csdn.net/liang_baikai/article/details/127849577
下载完成后,将其解压到/usr/local下
2. Adaface模型下载
https://github.com/mk-minchul/AdaFace?tab=readme-ov-file
WebFace4M模型准确率最高,R50 WebFace4M和R100 WebFace12M的准确率十分接近,但耗时却低了不少,所以建议使用R50 WebFace4M
3. 模型转换
下载Adaface源码,并将下面代码放到其目录下执行即可
model_trans.py
import torch
import torch.nn as nn
from head import AdaFace
import net
import onnxruntime as ort
import numpy as np
import onnx# 加载模型
adaface_models = {
# 'ir_101':"./adaface_ir101_ms1mv2.ckpt",'ir_50':"./adaface_ir50_webface4m.ckpt",
}
architecture = 'ir_50'model = net.build_model(architecture)
#model = AdaFace()
statedict = torch.load(adaface_models[architecture],map_location=torch.device('cpu'),weights_only=True)['state_dict']
model_statedict = {key[6:]:val for key, val in statedict.items() if key.startswith('model.')}model.load_state_dict(model_statedict, strict=True)for p in model.parameters():p.requires_grad = Falsemodel.eval()
device = torch.device("cpu");
model_cpu = model.to(device)# 创建一个示例输入
example_input = torch.rand(1, 3, 112, 112) # 假设输入大小为 (1, 3, 112, 112)# 转换为 TorchScript
traced_model = torch.jit.trace(model_cpu, example_input)# 保存模型
traced_model.save('adaface.pt')# 导出为 ONNX 格式
#onnx_file_path = 'adaface.onnx' # 输出文件名
#torch.onnx.export(model, example_input, onnx_file_path,
# export_params=True)#opset_version=11, # ONNX 版本#do_constant_folding=True, # 是否进行常量折叠#input_names=['input'], # 输入名称#output_names=['output'], # 输出名称#dynamic_axes={'input': {0: 'batch_size'}, # 动态 batch size# 'output': {0: 'batch_size'}})
4. c++推理
4.1 前处理
- resize人脸图片为112x112
- 归一化
- BGR->RGB
- 转换为tensor
- N H W C->N C H W
- reshape 1,3,112,112(模型输入shape)
4.2 推理
- load model
- 读取图片
- 人脸检测对齐
- 前处理
- model.forward推理
#include <torch/script.h>
#include <iostream>
#include <memory>
#include <opencv2/opencv.hpp>torch::Tensor to_input(const cv::Mat& pil_rgb_image) {cv::Mat brg_img;cv::resize(pil_rgb_image, brg_img, cv::Size(112, 112));brg_img.convertTo(brg_img, CV_32FC3, 1.0 / 255.0);brg_img = (brg_img - 0.5) / 0.5;cv::cvtColor(brg_img, brg_img, cv::COLOR_BGR2RGB);torch::Tensor tensor = torch::from_blob(brg_img.data, {1, brg_img.rows, brg_img.cols, 3}, torch::kFloat32);tensor = tensor.permute({0, 3, 1, 2});tensor = tensor.reshape({1, 3, 112, 112});tensor = tensor.to(at::kCPU);return tensor;
}int main() {// 模型加载torch::jit::script::Module model;try {model = torch::jit::load("./adaface.pt");//model.eval();model.to(at::kCPU);} catch (const c10::Error& e) {std::cerr << "Error loading the model\n";return -1;}// 读取图片std::vector<std::string> images;getAllFiles("./images", images, {"jpg", "jpeg", "png"});// 人脸检测器初始化OpenCVFace open_cv_face;open_cv_face.Init("./models/face_detection_yunet_2023mar.onnx","./models/face_recognition_sface_2021dec.onnx", 0.9, 0.5);for (const auto &image_path : images){// Load an image using OpenCVcv::Mat orig_img = cv::imread(image_path);if (orig_img.empty()) {std::cerr << "Could not read the image\n";return -1;}auto detect_start = GetCurTimestamp();std::vector<cv::Mat> aligned_faces;// 人脸检测对齐open_cv_face.detectAndAlign(orig_img, aligned_faces);//std::cout<<"detect use time is "<< (GetCurTimestamp() - detect_start)<<std::endl;for (const auto &face:aligned_faces){cv::Mat img(face);auto img_tensor = to_input(img);// Inference 推理std::vector<torch::jit::IValue> inputs;inputs.push_back(img_tensor);auto output = model.forward(inputs);// Check if the output is a tupleif (output.isTuple()) {auto output_tuple = output.toTuple();if (output_tuple->elements().size() > 0) {at::Tensor output_tensor = output_tuple->elements()[0].toTensor();//std::cout << output_tensor << std::endl;} else {std::cerr << "Output tuple is empty\n";return -1;}} else {at::Tensor output_tensor = output.toTensor();//std::cout << output_tensor << std::endl;}}}return 0;
}
注意:本代码的人脸检测和对齐使用opencv的Yunet和SFace实现, 地址
4.3 编译运行
4.3.1 写CMakeLists.txt
本工程依赖opencv和libtorch,一并下载解压到/usr/local下即可。
cmake_minimum_required(VERSION 3.22.1)
project(adaface-demo)set(QMAKE_CXXFLAGS "-std=c++17")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)include_directories(/usr/local/include)
link_directories(/usr/local/lib)set(OPENCV_VERSION "4.9.0")
set(OPENCV_INSTALLATION_PATH "/usr/local/opencv4" CACHE PATH "Where to look for OpenCV installation")# Find OpenCV
find_package(OpenCV ${OPENCV_VERSION} REQUIRED HINTS ${OPENCV_INSTALLATION_PATH})if (AARCH64)set(Torch_DIR /usr/local/libtorch/lib/python3.10/site-packages/torch/share/cmake/Torch)
else ()set(Torch_DIR /usr/local/libtorch/share/cmake/Torch)
endif ()find_package(Torch REQUIRED)
include_directories(${TORCH_INCLUDE_DIRS})AUX_SOURCE_DIRECTORY(./src DIR_SRCS)
add_executable(adaface-demo ${DIR_SRCS})target_link_libraries(adaface-demo ${OpenCV_LIBS} ${TORCH_LIBRARIES})
4.3.2 编译
mkdir build
cd build
cmake ..
4.3.3 运行
将模型文件adaface.py拷贝到bin目录下
cd ../bin
./main
相关文章:

人脸识别Adaface之libpytorch部署
目录 1. libpytorch下载2. Adaface模型下载3. 模型转换4. c推理4.1 前处理4.2 推理4.3 编译运行4.3.1 写CMakeLists.txt4.3.2 编译4.3.3 运行 1. libpytorch下载 参考: https://blog.csdn.net/liang_baikai/article/details/127849577 下载完成后,将其解…...
vue3+echarts+websocket分时图与K线图实时推送
一、父组件代码: <template> <div class"chart-box" v-loading"loading"> <!-- tab导航栏 --> <div class"tab-box"> <div class"tab-list"> <div v-for"(item, index) in tabList…...
小程序开发实战项目:构建简易待办事项列表
随着移动互联网的飞速发展,小程序以其便捷性、即用即走的特点,成为了连接用户与服务的重要桥梁。无论是电商平台的购物助手,还是餐饮行业的点餐系统,小程序都在各个领域发挥着巨大的作用。 小程序开发基础 1. 小程序简介 小程序是…...

SD Express 卡漏洞导致笔记本电脑和游戏机遭受内存攻击
Positive Technologies 最近发布的一份报告揭示了一个名为 DaMAgeCard 的新漏洞,攻击者可以利用该漏洞利用 SD Express 内存卡直接访问系统内存。 该漏洞利用了 SD Express 中引入的直接内存访问 (DMA) 功能来加速数据传输速度,但也为对支持该标准的设备…...

前端node环境安装:nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置)
需求:在做前端开发的时候,有的时候 这个项目需要 node 14 那个项目需要 node 16,我们也不能卸载 安装 。这岂不是很麻烦。这个时候 就需要 一个工具 来管理我们的 node 版本和 npm 版本。 下面就分享一个 nvm 工具 用来管理 node 版本。 这个…...

java之集合(详细-Map,Set,List)
1集合体系概述 1.1集合的概念 集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用。 1.2集合分类 集合分为单列集合和多列集合 Collection代表单列集合,每个元素(数据ÿ…...
常见LeetCode-Saw200
用来记录需要知道见过的题型: LeetCode2-两数相加 说明:以链表的形势给了你每个位的数字,而且是逆序,直接从开头(个位)遍历相加。带上进位即可。有一个为空就直接计算另一个和进位。 LeetCode-3.无重复字符…...

Unity 制作一个视频播放器(打包后,可在外部编辑并放置新的视频)
效果展示: 在这里,我把视频名称(Json)和对应的视频资源都放在了StreamingAssets文件夹下,以便于打包后,客户还可以自己在外部增加、删除、修改对应的视频资料。 如有需要,请联细抠抠。...

MySQL-SQL语句
文章目录 一. SQL语句介绍二. SQL语句分类1. 数据定义语言:简称DDL(Data Definition Language)2. 数据操作语言:简称DML(Data Manipulation Language)3. 数据查询语言:简称DQL(Data Query Language)4. 数据控制语言:简称DCL(Data …...
腾讯微信大数据面试题及参考答案
DNS 协议是否使用 UDP? DNS(Domain Name System)协议主要使用 UDP(User Datagram Protocol),但也会使用 TCP(Transmission Control Protocol)。 UDP 是一种无连接的传输协议,它的特点是简单、高效。DNS 在进行域名解析时,大部分情况下使用 UDP。因为 UDP 的开销小,对…...

Python跳动的爱心
系列文章 序号直达链接表白系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4Python李峋同款可写字版跳动的爱心5Python流星雨代码6Python漂浮爱心代码7Python爱心光波代码8Python普通的玫瑰花代码9Python炫酷的玫瑰花代码10Python多…...

计算机启动过程 | Linux 启动流程
注:本文为“计算机启动、 Linux 启动”相关文章合辑。 替换引文部分不清晰的图。 探索计算机的启动过程 Aleksandr Goncharov 2023/04/21 很多人对计算机的启动方式很感兴趣。只要设备开启,这就是魔法开始和持续的地方。在本文中,我们将概…...

反射简单介绍
反射就是从类里拿东西 有的人可能会想为什么不能用io流,从上往下一行一行的读也能获取类中的信息,为什么要用反射呢? 假如我们io流,从左到右一行一行的读取数据,如果碰到局部变量和成员变量同名,怎么区分&a…...

工具篇--GitHub Desktop 使用
文章目录 前言一、GitHub Desktop 的使用:1.1 通过官网下载GitHub Desktop和安装:1.2 安装和使用:1.2.1 填充自己的标识:1.2.3 克隆项目:1.2.4 git 常用忽略项配置: 二、代码的更新和提交:2.1 代…...

单臂路由配置
知识点 单臂路由指在路由器上的一个接口配置子接口(逻辑接口)来实现不同vlan间通信 路由器上的每个物理接口都可以配置多个子接口(逻辑接口) 公司的财务部、技术部和业务部有多台计算机,它们使用一台二层交换机进行互…...

河工oj第七周补题题解2024
A.GO LecturesⅠ—— Victory GO LecturesⅠ—— Victory - 问题 - 软件学院OJ 代码 统计 #include<bits/stdc.h> using namespace std;double b, w;int main() {for(int i 1; i < 19; i ) {for(int j 1; j < 19; j ) {char ch; cin >> ch;if(ch B) b …...
卷积的数学原理与作用
一、一维卷积 (一)定义 数学定义 给定一个输入序列 x [ x 1 , x 2 , ⋯ , x n ] x [x_1,x_2,\cdots,x_n] x[x1,x2,⋯,xn] 和一个卷积核(滤波器) k [ k 1 , k 2 , ⋯ , k m ] k [k_1,k_2,\cdots,k_m] k[k1,k2,⋯,…...
路由介绍.
RIB和FIB Routing Information Base(RIB),即路由信息库,是存储在路由器或联网计算机中的一个电子表格或类数据库,它保存着指向特定网络地址的路径信息,包括路径的路由度量值。RIB的主要目标是实现路由协议…...

CTFshow-命令执行(Web29-40)
CTFshow-命令执行(Web29-40) CTFWeb-命令执行漏洞过滤的绕过姿势_绕过空格过滤-CSDN博客 总结rce(远程代码执行各种sao姿势)绕过bypass_远程命令执行绕过-CSDN博客 对比两者的源代码,我们发现,cat指令把flag.php的内容导出后依…...
MySQL锁的类型有哪些
目录 共享锁(share lock): 排他锁(exclusivelock): 表锁(table lock): 行锁: 记录锁(Record lock): 页锁: 间隙锁: 基于锁的属性分类:共享锁,排他锁。 基于锁的粒…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...