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

效果

项目

代码

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可执行程序包免费下载

源码下载