C# OpenCvSharp Yolov8 Face Landmarks 人脸特征检测

embedded/2025/1/21 6:58:46/

目录

介绍

效果

模型信息

项目

代码

下载


介绍

github地址:https://github.com/derronqi/yolov8-face

yolov8 face detection with landmark

效果

模型信息

Model Properties

YOLOv8litetpose_model_trained_on_widerfaceyaml%0AauthorUltralytics%0Akpt_shape5_3%0Ataskpose%0AlicenseAGPL30_httpsultralyticscomlicense%0Aversion8085%0Astride32%0Abatch1%0Aimgsz640_640%0Anames0_face_32">description:Ultralytics YOLOv8-lite-t-pose model trained on widerface.yaml
author:Ultralytics
kpt_shape:[5, 3]
task:pose
license:AGPL-3.0 https://ultralytics.com/license
version:8.0.85
stride:32
batch:1
imgsz:[640, 640]
names:{0: ‘face’}

Inputs

name:images
tensor:Float[1, 3, 640, 640]

Outputs

name:output0
tensor:Float[1, 80, 80, 80]
name:884
tensor:Float[1, 80, 40, 40]
name:892
tensor:Float[1, 80, 20, 20]

项目

代码

GenerateProposal函数

public static unsafe void GenerateProposal (int inpHeight, int inpWidth, int reg_max, int num_class, float score_threshold, int feat_h, int feat_w, Mat output, List position_boxes, List confidences, List<List<OpenCvSharp.Point>> landmarks, int imgh, int imgw, float ratioh, float ratiow, int padh, int padw)
{
int stride = (int)Math.Ceiling((double)(inpHeight / feat_h));
int area = feat_h /* feat_w;

float/* ptr = (float/*)output.DataStart;
float/* ptr_cls = ptr + area /* reg_max /* 4;
float/* ptr_kp = ptr + area /* (reg_max /* 4 + num_class);for (int i = 0; i < feat_h; i++)
{for (int j = 0; j < feat_w; j++){int cls_id = -1;float max_conf = -10000;int index = i /* feat_w + j;for (int k = 0; k < num_class; k++){float conf = ptr_cls[k /* area + index];if (conf > max_conf){max_conf = conf;cls_id = k;}}float box_prob = Common.sigmoid_x(max_conf);if (box_prob > score_threshold){float[] pred_ltrb = new float[4];float[] dfl_value = new float[reg_max];float[] dfl_softmax = new float[reg_max];for (int k = 0; k < 4; k++){for (int n = 0; n < reg_max; n++){dfl_value[n] = ptr[(k /* reg_max + n) /* area + index];}Common.softmax_(ref dfl_value, ref dfl_softmax, reg_max);float dis = 0f;for (int n = 0; n < reg_max; n++){dis += n /* dfl_softmax[n];}pred_ltrb[k] = dis /* stride;}float cx = (j + 0.5f) /* stride;float cy = (i + 0.5f) /* stride;float xmin = Math.Max((cx - pred_ltrb[0] - padw) /* ratiow, 0f);  ///还原回到原图float ymin = Math.Max((cy - pred_ltrb[1] - padh) /* ratioh, 0f);float xmax = Math.Min((cx + pred_ltrb[2] - padw) /* ratiow, (float)(imgw - 1));float ymax = Math.Min((cy + pred_ltrb[3] - padh) /* ratioh, (float)(imgh - 1));Rect box = new Rect((int)xmin, (int)ymin, (int)(xmax - xmin), (int)(ymax - ymin));position_boxes.Add(box);confidences.Add(box_prob);List<OpenCvSharp.Point> kpts = new List<OpenCvSharp.Point>();for (int k = 0; k < 5; k++){float x = ((ptr_kp[(k /* 3) /* area + index] /* 2 + j) /* stride - padw) /* ratiow;  ///还原回到原图float y = ((ptr_kp[(k /* 3 + 1) /* area + index] /* 2 + i) /* stride - padh) /* ratioh;kpts.Add(new OpenCvSharp.Point((int)x, (int)y));}landmarks.Add(kpts);}}
}

}

	using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace OpenCvSharp_Yolov8_Demo
{public partial class frmMain : Form{public frmMain(){InitializeComponent();}string fileFilter = "/*./*|/*.bmp;/*.jpg;/*.jpeg;/*.tiff;/*.tiff;/*.png";string image_path = "";string startupPath;DateTime dt1 = DateTime.Now;DateTime dt2 = DateTime.Now;string model_path;Mat image;Mat result_image;Net opencv_net;Mat BN_image;StringBuilder sb = new StringBuilder();int reg_max = 16;int num_class = 1;int inpWidth = 640;int inpHeight = 640;float score_threshold = 0.25f;float nms_threshold = 0.5f;private void Form1_Load(object sender, EventArgs e){startupPath = System.Windows.Forms.Application.StartupPath;model_path = startupPath + "\\yolov8-lite-t.onnx";//初始化网络类,读取本地模型opencv_net = CvDnn.ReadNetFromOnnx(model_path);}private void button1_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox1.Image = null;image_path = ofd.FileName;pictureBox1.Image = new Bitmap(image_path);textBox1.Text = "";image = new Mat(image_path);pictureBox2.Image = null;}private void button2_Click(object sender, EventArgs e){if (image_path == ""){return;}int newh = 0, neww = 0, padh = 0, padw = 0;Mat resize_img = Common.ResizeImage(image, inpHeight, inpWidth, ref newh, ref neww, ref padh, ref padw);float ratioh = (float)image.Rows / newh, ratiow = (float)image.Cols / neww;//数据归一化处理BN_image = CvDnn.BlobFromImage(resize_img, 1 / 255.0, new OpenCvSharp.Size(inpWidth, inpHeight), new Scalar(0, 0, 0), true, false);//配置图片输入数据opencv_net.SetInput(BN_image);//模型推理,读取推理结果Mat[] outs = new Mat[3] { new Mat(), new Mat(), new Mat() };string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();dt1 = DateTime.Now;opencv_net.Forward(outs, outBlobNames);dt2 = DateTime.Now;List<Rect> position_boxes = new List<Rect>();List<float> confidences = new List<float>();List<List<OpenCvSharp.Point>> landmarks = new List<List<OpenCvSharp.Point>>();Common.GenerateProposal(inpHeight, inpWidth, reg_max, num_class, score_threshold, 40, 40, outs[0], position_boxes, confidences, landmarks, image.Rows, image.Cols, ratioh, ratiow, padh, padw);Common.GenerateProposal(inpHeight, inpWidth, reg_max, num_class, score_threshold, 20, 20, outs[1], position_boxes, confidences, landmarks, image.Rows, image.Cols, ratioh, ratiow, padh, padw);Common.GenerateProposal(inpHeight, inpWidth, reg_max, num_class, score_threshold, 80, 80, outs[2], position_boxes, confidences, landmarks, image.Rows, image.Cols, ratioh, ratiow, padh, padw);//NMS非极大值抑制int[] indexes = new int[position_boxes.Count];CvDnn.NMSBoxes(position_boxes, confidences, score_threshold, nms_threshold, out indexes);List<Rect> re_result = new List<Rect>();List<List<OpenCvSharp.Point>> re_landmarks = new List<List<OpenCvSharp.Point>>();List<float> re_confidences = new List<float>();for (int i = 0; i < indexes.Length; i++){int index = indexes[i];re_result.Add(position_boxes[index]);re_landmarks.Add(landmarks[index]);re_confidences.Add(confidences[index]);}if (re_result.Count > 0){sb.Clear();sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");sb.AppendLine("--------------------------");//将识别结果绘制到图片上result_image = image.Clone();for (int i = 0; i < re_result.Count; i++){Cv2.Rectangle(result_image, re_result[i], new Scalar(0, 0, 255), 2, LineTypes.Link8);Cv2.PutText(result_image, "face-" + re_confidences[i].ToString("0.00"),new OpenCvSharp.Point(re_result[i].X, re_result[i].Y - 10),HersheyFonts.HersheySimplex, 1, new Scalar(0, 0, 255), 2);foreach (var item in re_landmarks[i]){Cv2.Circle(result_image, item, 4, new Scalar(0, 255, 0), -1);}sb.AppendLine(string.Format("{0}:{1},({2},{3},{4},{5})", "face", re_confidences[i].ToString("0.00"), re_result[i].TopLeft.X, re_result[i].TopLeft.Y, re_result[i].BottomRight.X, re_result[i].BottomRight.Y));}pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());textBox1.Text = sb.ToString();}else{textBox1.Text = "无信息";}}}
}

下载

exe可执行程序包免费下载

原文地址


http://www.ppmy.cn/embedded/155703.html

相关文章

Springboot中使用Elasticsearch(部署+使用+讲解 最完整)

目录 引言 一、docker中安装Elasticsearch 1、创建es专有的网络 2、开放端口 3、在es-net网络上安装es和kibana 4、可能出现的问题 5、测试 6、安装IK分词器 7、测试IK分词器 二、结合业务实战 1、准备依赖 2、配置yml 3、读取yml配置 4、准备es配置类 5、编写测…

Wi-Fi 7、Wi-Fi 6 与 5G、4G 的全方位对比

随着无线通信技术的飞速发展&#xff0c;Wi-Fi 7、Wi-Fi 6&#xff0c;以及5G、4G 已经成为人们生活和工作中不可或缺的网络技术。无论是家庭网络、高速移动通信&#xff0c;还是工业物联网&#xff0c;这些技术都在发挥各自的作用。那么&#xff0c;它们之间有什么区别&#x…

使用numpy求解线性代数相关问题

在numpy中有numpy.array类型和numpy.mat类型&#xff0c;前者是数组类型&#xff0c;后者是矩阵类型。数组类型相乘是逐元素相乘&#xff0c;而矩阵类型相乘则是矩阵乘法。 以下使用numpy.array类型来进行线性代数问题求解。 矩阵的转置&#xff1a; A.T import numpy as n…

Spring Boot 3.4 正式发布,结构化日志!

1 从 Spring Boot 3.3 升级到 3.4 1.1 RestClient 和 RestTemplate 新增对 RestClient 和 RestTemplate 自动配置的支持&#xff0c;可用 Reactor Netty 的 HttpClient 或 JDK 的 HttpClient。支持的客户端优先级&#xff1a; Apache HTTP Components (HttpComponentsClient…

简单介绍JSONStream的使用

地址 作用 这个模块是根据需要筛选出json数据中自己所需要的数据 使用 var JSONStream require("JSONStream"); var parse require("fast-json-parse"); var fs require("fs");fs.createReadStream("./time.json").pipe(JSONSt…

C链表的一些基础知识

一、链表的基本概念 链表是一种常见的线性数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含数据部分和指向下一个节点的指针&#xff08;单链表情况&#xff09;。通过指针将各个节点连接起来&#xff0c;与数组不同&#xff0c;链表在内存中的存储不是连续的…

在 Vue 3 中实现插件化架构:设计可扩展的前端插件系统

随着前端项目的复杂性不断提升&#xff0c;模块化和可扩展性在架构设计中的重要性愈加突出。Vue 3 的 Composition API 和插件机制为我们实现插件化架构提供了便利。本文将深入探讨如何在 Vue 3 中构建一个高效、灵活的插件系统&#xff0c;为大型前端项目的扩展性打下基础。 …

如何使用Spring Boot框架整合Redis:超详细案例教程

目录 # 为什么选择Spring Boot与Redis整合&#xff1f; 1. 更新 pom.xml 2. 配置application.yml 3. 创建 Redis 配置类 4. Redis 操作类 5. 创建控制器 6. 启动应用程序 7. 测试 # 为什么选择Spring Boot与Redis整合&#xff1f; 将Spring Boot与Redis整合可以充分利…