人脸识别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

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

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

相关文章

Elasticsearch高性能实践

前言 本方案主要从运维层面分析es是实际生产使用过程中的参数优化&#xff0c;深入理解es各个名词及含义&#xff0c;深入分析es的使用过程中应注意的点&#xff0c;详细解释参数设置的原因以及目的&#xff0c;主要包括系统层面&#xff0c;参数层面。除此之外&#xff0c;优…

在idea中使用mysql(超详细)

一、连接mysql 在IDE开发工具中也是可以使用mysql的&#xff0c;这里以开发java常用的IntelliJ IDEA为例。 1. 打开idea&#xff0c;右上角有数据库侧边栏&#xff0c;打开侧边栏点击加号->数据源&#xff0c;可以看到支持很多数据库&#xff0c;选择mysql。 2. 首次使用需…

Python简化算法工具——“按位运算”

一、六种常见的“按位运算” 1.与&#xff08;&&#xff09;运算 运算规则&#xff1a;对两个整数对应的二进制位进行操作&#xff0c;当两个相应的二进制位都为1时&#xff0c;该位的结果才为1&#xff0c;否则为0。 a5 #0101b7 #0111print(a&b)#a&b0101#输出对…

Modbus转Profibus网关:打通多电机交流控制,打造自动化神器

在工业控制领域&#xff0c;Modbus和Profibus是两种非常常见的通信协议。Modbus由于其简单的结构、易于实现的特点被广泛应用在各种电子设备中&#xff0c;而Profibus则以其稳定性和实时性在大型自动化系统中占有一席之地。但是&#xff0c;有时候我们需要将这两种协议进行转换…

C++重点和练习

作业1&#xff1a;实现类中有类的几个特殊成员函数 #include <iostream>using namespace std;class Person {string name;int *age; public:Person():name("none"),age(new int(0)){}Person(int age):age(new int(age)){}Person(string name,int age):name(na…

亚马逊云科技用生成式AI,向开发的复杂性动手了

生成式 AI、分布式扩展功能全面进化&#xff0c;还降价了。 同一天的发布&#xff0c;完全不同的方向。 今天凌晨&#xff0c;云计算巨头亚马逊云科技的 re:Invent 与大号创业公司 OpenAI 的发布「撞了车」。后者公布了一系列生成式 AI 应用&#xff0c;价格更贵、性能更强大&a…

【操作系统】实验二:观察Linux,使用proc文件系统

实验二 观察Linux&#xff0c;使用proc文件系统 实验目的&#xff1a;学习Linux内核、进程、存储和其他资源的一些重要特征。读/proc/stat文件&#xff0c;计算并显示系统CPU占用率和用户态CPU占用率。&#xff08;编写一个程序使用/proc机制获得以及修改机器的各种资源参数。…

day2 数据结构 结构体的应用

思维导图 小练习&#xff1a; 定义一个数组&#xff0c;用来存放从终端输入的5个学生的信息【学生的信息包含学生的姓名、年纪、性别、成绩】 1>封装函数 录入5个学生信息 2>封装函数 显示学生信息 3>封装函数 删除第几个学生信息&#xff0c;删除后调用显示学…

SQL Server:只有MDF文件,如何附加数据库

第一步&#xff1a;先新建一个同名数据库&#xff0c;然后停止sql服务&#xff0c;删除新建数据库.ldf文件。 第二步&#xff1a;将要附加的数据库的.mdf文件覆盖刚新建的.mdf文件&#xff0c;并重启sql服务。 第三步&#xff1a;这时数据库DATA目录下只有一个.mdf文件&#xf…

React开发高级篇 - React Hooks以及自定义Hooks实现思路

Hooks介绍 Hooks是react16.8以后新增的钩子API&#xff1b; 目的&#xff1a;增加代码的可复用性&#xff0c;逻辑性&#xff0c;弥补无状态组件没有生命周期&#xff0c;没有数据管理状态state的缺陷。 为什么要使用Hooks&#xff1f; 开发友好&#xff0c;可扩展性强&#…

jmeter调整字号无法生效?

调整之前如上图&#xff0c;字体非常小&#xff0c;哪怕我设置的字号是48 查阅了资料&#xff0c;试了几次&#xff0c;解决办法如下&#xff1a; 用编辑器打开jmeter.bat 在echo off的下一行添加以下代码 set JVM_ARGS%JVM_ARGS% -Dswing.plaf.metal.controlFontDialog-20…

密码学——密码学基础、散列函数与数字签名

1.密码学概述 是信息安全的基础和核心&#xff0c;是防范各种安全威胁的重要手段&#xff0c;信息安全的许多相关知识都与密码学相关。 密码学发展 密码学是一门古老而又年轻的学科 &#xff0c;几千年以前就存在&#xff0c;至今仍在发展演进。地位非常重要甚至起决定性作用…

知识图谱8:深度学习各种小模型

1、知识图谱的展示有很多工具 Neo4j Browser - - - - 浏览器版本 Neo4j Desktop - - - - 桌面版本 graphX - - - - 可以集成到Neo4j Desktop Neo4j 提供的 Neo4j Bloom 是用户友好的可视化工具&#xff0c;适合非技术用户直观地浏览图数据。Cypher 是其核心查询语言&#xf…

Python | 数据可视化中常见的4种标注及示例

在Python的数据可视化中&#xff0c;标注&#xff08;Annotation&#xff09;技术是一种非常有用的工具&#xff0c;它可以帮助用户更准确地解释图表中的数据和模式。在本文中&#xff0c;将带您了解使用Python实现数据可视化时应该了解的4种标注。 常见的标注方式 文本标注箭…

在Goland中对goroutine协程断点调试

在Goland中对goroutine协程断点调试 环境: Goland 参考了 chatgpt 的回复 进行断点调试的代码 package mainimport ("fmt""sync""time" )// worker 模拟处理任务 func worker(id int, wg *sync.WaitGroup) {defer wg.Done() // 确保任务完成后…

深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解

目录 深入理解 JavaScript 中的 Array.find() 方法&#xff1a;原理、性能优势与实用案例详解 一、引言&#xff1a;为什么要使用Array.find() 二、Array.find()的使用与技巧 1、基础语法 2、返回值 3、使用技巧 三、Array.find()的优势与实际应用案例 1、利用返回引用…

Docker 安装 Jenkins:2.346.3

准备&#xff1a;已安装Docker&#xff0c;已配置服务器安全组规则 1581 1、拉取镜像 [rootTseng ~]# docker pull jenkins/jenkins:2.346.3 2.346.3: Pulling from jenkins/jenkins 001c52e26ad5: Pull complete 6b8dd635df38: Pull complete 2ba4c74fd680: Pull complet…

Datawhale AI 冬令营(第一期)定制你的第一个专属模型-学习笔记

最近我报名参加了Datawhale组织的主题为“动手学系列&#xff0c;人人都能应用的AI”的Datawhale AI冬令营&#xff08;第一期&#xff09;。 本次学习一共12天&#xff0c;从12月10日-12月21日&#xff0c;学习会包含【跑通速通手册】&#xff0c;【学习大模型微调&数据集…

异常安全重启运行机制:健壮的Ai模型训练自动化

文章目录 前言一、热力图主函数代码1、正规N图热力图运行代码2、重新迭代循环求解方法 二、中断重启继续推理或训练1、封装含参主函数2、终止重启进程管理方法1、终止启动源码2、源码解读 三、终止启动主函数源码解读1、终止启动源码2、源码解读关键点解析 四、完整代码Demo1、…

Redis01

springbootredis 特点 1.高效性 2.支持多种数据结构 String,list,set,hash.zset 3.稳定性&#xff1a;持久化&#xff0c;主从复制&#xff08;集群&#xff09; 4.其他特性&#xff1a;支持过期时间&#xff0c;支持事务&#xff0c;消息订阅。 安装 1.下载安装包 redis官…