Table of Contents
introduce
Effect
Model information
project
code
download
Introduction
Github address: https://github.com/derronqi/yolov8-face
yolov8 face detection with landmark
Effect
Model information
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]
————————————————– ————-
project
code
GenerateProposal function
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> 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); ///Restore to the original image
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
for (int k = 0; k < 5; k + + )
{
float x = ((ptr_kp[(k * 3) * area + index] * 2 + j) * stride – padw) * ratiow; ///Restore to original image
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"; //Initialize the network class and read the local model 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; //Data normalization processing BN_image = CvDnn.BlobFromImage(resize_img, 1 / 255.0, new OpenCvSharp.Size(inpWidth, inpHeight), new Scalar(0, 0, 0), true, false); //Configure image input data opencv_net.SetInput(BN_image); //Model inference, read inference results 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 non-maximum suppression 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("Inference time consumption:" + (dt2 - dt1).TotalMilliseconds + "ms"); sb.AppendLine("--------------------------"); //Draw the recognition results onto the picture 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 = "No information"; } } } }
Download
exe executable package free download
Source code download
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. OpenCV skill tree Home page Overview 23664 people are learning the system