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

介绍

github地址:

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

yolov8 face detection with landmark

效果

373bb534cc25b22c3490734b3dae6e4e.png

a9b0b992872310f10ddc4c24cfad2950.png

模型信息

Model Properties
-------------------------
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]
---------------------------------------------------------------

项目

VS2022

.net framework 4.8

OpenCvSharp 4.8

Microsoft.ML.OnnxRuntime 1.16.2

355d62ba74aa53a3416f3d495da4efb5.png

代码

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 = "无信息";
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: shape_predictor_68_face_landmarks.dat是一个预训练的人脸特征检测模型。这个模型可以用来识别人脸图像中的68个重要特征点,包括眼睛、眉毛、鼻子、嘴巴等部位的位置。使用这个模型可以方便地进行人脸关键点定位,为人脸识别、表情分析、姿势识别等领域的应用提供基础的数据支持。 这个模型是通过深度学习算法在大规模人脸数据集上进行训练得到的。在训练过程中,模型通过学习人脸图像中特征点的规律和模式,能够准确地预测出新的人脸图像中的特征点位置。 使用shape_predictor_68_face_landmarks.dat模型时,我们首先需要将待检测人脸图像输入到模型中。模型会分析图像中的人脸区域,并自动识别出特征点的位置。我们可以根据预测的特征点位置来实现不同的应用需求,比如通过计算眼睛的位置和距离来实现眼球注视方向的识别,或者通过分析嘴唇的形状来识别出人的表情。 shape_predictor_68_face_landmarks.dat模型的优势是速度快、准确性高。同时,它还支持多种编程语言,如Python、C++等,可以方便地集成到各种软件平台中。 总之,shape_predictor_68_face_landmarks.dat是一个强大的人脸特征检测模型,可以在人脸识别、表情分析、姿势识别等应用中发挥重要作用。 ### 回答2: shape_predictor_68_face_landmarks.dat是一个预训练的人脸特征检测模型。这个模型可以用于检测人脸图像中的68个特征点,包括眼睛、眉毛、鼻子、嘴巴以及下巴等区域。这些特征点可以用来帮助定位人脸,进一步进行人脸识别、表情分析、姿态估计等任务。 该预训练模型使用了大量标注好的人脸图像进行训练,经过深度学习算法学习到了图像中不同区域与特征点之间的相关性。在使用该模型时,我们可以将人脸图像输入模型,模型会输出一个包含68个特征点的向量。每个特征点包含其在图像中的坐标位置信息。 通过使用shape_predictor_68_face_landmarks.dat模型,我们可以方便地在图像或视频中检测人脸的位置,并且得到每个人脸的68个特征点的位置信息。这对于人脸相关任务非常有帮助,例如在人脸识别中,可以用这些特征点来计算人脸特征向量,进而进行比对和识别。在表情分析中,可以通过监测特定的特征点位置变化来推断人脸的表情状态。姿态估计中,可以利用特征点的位置信息来估计人脸的头部姿态。 总之,shape_predictor_68_face_landmarks.dat是一个非常有用的预训练的人脸特征检测模型,可以辅助实现人脸识别、表情分析、姿态估计等多种人脸相关的任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值