当前位置: 首页 > news >正文

人脸识别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下载 参考&#xff1a; https://blog.csdn.net/liang_baikai/article/details/127849577 下载完成后&#xff0c;将其解…...

vue3+echarts+websocket分时图与K线图实时推送

一、父组件代码&#xff1a; <template> <div class"chart-box" v-loading"loading"> <!-- tab导航栏 --> <div class"tab-box"> <div class"tab-list"> <div v-for"(item, index) in tabList…...

小程序开发实战项目:构建简易待办事项列表

随着移动互联网的飞速发展&#xff0c;小程序以其便捷性、即用即走的特点&#xff0c;成为了连接用户与服务的重要桥梁。无论是电商平台的购物助手&#xff0c;还是餐饮行业的点餐系统&#xff0c;小程序都在各个领域发挥着巨大的作用。 小程序开发基础 1. 小程序简介 小程序是…...

SD Express 卡漏洞导致笔记本电脑和游戏机遭受内存攻击

Positive Technologies 最近发布的一份报告揭示了一个名为 DaMAgeCard 的新漏洞&#xff0c;攻击者可以利用该漏洞利用 SD Express 内存卡直接访问系统内存。 该漏洞利用了 SD Express 中引入的直接内存访问 (DMA) 功能来加速数据传输速度&#xff0c;但也为对支持该标准的设备…...

前端node环境安装:nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置)

需求&#xff1a;在做前端开发的时候&#xff0c;有的时候 这个项目需要 node 14 那个项目需要 node 16&#xff0c;我们也不能卸载 安装 。这岂不是很麻烦。这个时候 就需要 一个工具 来管理我们的 node 版本和 npm 版本。 下面就分享一个 nvm 工具 用来管理 node 版本。 这个…...

java之集合(详细-Map,Set,List)

1集合体系概述 1.1集合的概念 集合是一种容器&#xff0c;用来装数据的&#xff0c;类似于数组&#xff0c;但集合的大小可变&#xff0c;开发中也非常常用。 1.2集合分类 集合分为单列集合和多列集合 Collection代表单列集合&#xff0c;每个元素&#xff08;数据&#xff…...

常见LeetCode-Saw200

用来记录需要知道见过的题型&#xff1a; LeetCode2-两数相加 说明&#xff1a;以链表的形势给了你每个位的数字&#xff0c;而且是逆序&#xff0c;直接从开头&#xff08;个位&#xff09;遍历相加。带上进位即可。有一个为空就直接计算另一个和进位。 LeetCode-3.无重复字符…...

Unity 制作一个视频播放器(打包后,可在外部编辑并放置新的视频)

效果展示&#xff1a; 在这里&#xff0c;我把视频名称&#xff08;Json&#xff09;和对应的视频资源都放在了StreamingAssets文件夹下&#xff0c;以便于打包后&#xff0c;客户还可以自己在外部增加、删除、修改对应的视频资料。 如有需要&#xff0c;请联细抠抠。...

MySQL-SQL语句

文章目录 一. SQL语句介绍二. SQL语句分类1. 数据定义语言&#xff1a;简称DDL(Data Definition Language)2. 数据操作语言&#xff1a;简称DML(Data Manipulation Language)3. 数据查询语言&#xff1a;简称DQL(Data Query Language)4. 数据控制语言&#xff1a;简称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 启动流程

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

反射简单介绍

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

工具篇--GitHub Desktop 使用

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

单臂路由配置

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

河工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 …...

卷积的数学原理与作用

一、一维卷积 &#xff08;一&#xff09;定义 数学定义 给定一个输入序列 x [ x 1 , x 2 , ⋯ , x n ] x [x_1,x_2,\cdots,x_n] x[x1​,x2​,⋯,xn​] 和一个卷积核&#xff08;滤波器&#xff09; k [ k 1 , k 2 , ⋯ , k m ] k [k_1,k_2,\cdots,k_m] k[k1​,k2​,⋯,…...

路由介绍.

RIB和FIB Routing Information Base&#xff08;RIB&#xff09;&#xff0c;即路由信息库&#xff0c;是存储在路由器或联网计算机中的一个电子表格或类数据库&#xff0c;它保存着指向特定网络地址的路径信息&#xff0c;包括路径的路由度量值。RIB的主要目标是实现路由协议…...

CTFshow-命令执行(Web29-40)

CTFshow-命令执行(Web29-40) CTFWeb-命令执行漏洞过滤的绕过姿势_绕过空格过滤-CSDN博客 总结rce&#xff08;远程代码执行各种sao姿势&#xff09;绕过bypass_远程命令执行绕过-CSDN博客 对比两者的源代码&#xff0c;我们发现&#xff0c;cat指令把flag.php的内容导出后依…...

MySQL锁的类型有哪些

目录 共享锁(share lock)&#xff1a; 排他锁(exclusivelock)&#xff1a; 表锁(table lock)&#xff1a; 行锁&#xff1a; 记录锁(Record lock)&#xff1a; 页锁&#xff1a; 间隙锁&#xff1a; 基于锁的属性分类&#xff1a;共享锁&#xff0c;排他锁。 基于锁的粒…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...