C# OpenCvSharp DNN FreeYOLO 人脸检测人脸图像质量评估

目录

效果

模型信息

yolo_free_huge_widerface_192x320.onnx

face-quality-assessment.onnx

项目

代码

frmMain.cs

FreeYoloFace

FaceQualityAssessment.cs

下载


C# OpenCvSharp DNN FreeYOLO 人脸检测&人脸图像质量评估

效果

模型信息

yolo_free_huge_widerface_192x320.onnx


Inputs
-------------------------
name:input
tensor:Float[1, 3, 192, 320]
---------------------------------------------------------------

Outputs
-------------------------
name:output
tensor:Float[1, 1260, 6]
---------------------------------------------------------------

face-quality-assessment.onnx

Inputs
-------------------------
name:input
tensor:Float[1, 3, 112, 112]
---------------------------------------------------------------

Outputs
-------------------------
name:quality
tensor:Float[1, 10]
---------------------------------------------------------------

项目

代码

frmMain.cs

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace OpenCvSharp_DNN_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        StringBuilder sb = new StringBuilder();

        Mat image;
        Mat result_image;

        FaceQualityAssessment fqa = new FaceQualityAssessment("model/face-quality-assessment.onnx");
        FreeYoloFace face = new FreeYoloFace("model/yolo_free_huge_widerface_192x320.onnx");

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            image_path = "test_img/1.jpg";
            pictureBox1.Image = new Bitmap(image_path);
        }

        private unsafe void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "检测中,请稍等……";
            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }
            pictureBox2.Image = null;
            sb.Clear();
            Application.DoEvents();

            image = new Mat(image_path);

            dt1 = DateTime.Now;
            List<Face> ltFace = face.Detect(image);
            dt2 = DateTime.Now;

            if (ltFace.Count > 0)
            {
                sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");
                result_image = image.Clone();
                foreach (var item in ltFace)
                {
                    Mat crop_img = new Mat(image, item.rect);
                    float fqa_prob_mean = fqa.Detect(crop_img);
                    crop_img.Dispose();
                    Cv2.Rectangle(result_image, new OpenCvSharp.Point(item.rect.X, item.rect.Y), new OpenCvSharp.Point(item.rect.X + item.rect.Width, item.rect.Y + item.rect.Height), new Scalar(0, 0, 255), 2);
                    string label = "prob:" + item.prob.ToString("0.00") + " fqa_score:" + fqa_prob_mean.ToString("0.00");
                    sb.AppendLine(label);
                    Cv2.PutText(result_image, label, new OpenCvSharp.Point(item.rect.X, item.rect.Y - 5), HersheyFonts.HersheySimplex, 1, new Scalar(0, 0, 255), 2);
                }
                pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
                textBox1.Text = sb.ToString();
            }
            else
            {
                textBox1.Text = "未检测到人脸";
            }
        }

        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox2.Image);
        }

        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox1.Image);
        }
    }
}

FreeYoloFace.cs

using OpenCvSharp.Dnn;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;namespace OpenCvSharp_DNN_Demo
{public class FreeYoloFace{float confThreshold;float nmsThreshold;int num_stride = 3;float[] strides = new float[3] { 8.0f, 16.0f, 32.0f };string modelpath;int inpHeight;int inpWidth;List<string> class_names;int num_class;Net opencv_net;Mat BN_image;Mat image;public FreeYoloFace(string modelpath){opencv_net = CvDnn.ReadNetFromOnnx(modelpath);class_names = new List<string> { "face" };num_class = 1;confThreshold = 0.8f;nmsThreshold = 0.5f;inpHeight = 192;inpWidth = 320;}unsafe public List<Face> Detect(Mat image){List<Face> ltFace = new List<Face>();float ratio = Math.Min(1.0f * inpHeight / image.Rows, 1.0f * inpWidth / image.Cols);int neww = (int)(image.Cols * ratio);int newh = (int)(image.Rows * ratio);Mat dstimg = new Mat();Cv2.Resize(image, dstimg, new OpenCvSharp.Size(neww, newh));Cv2.CopyMakeBorder(dstimg, dstimg, 0, inpHeight - newh, 0, inpWidth - neww, BorderTypes.Constant);BN_image = CvDnn.BlobFromImage(dstimg);//配置图片输入数据opencv_net.SetInput(BN_image);//模型推理,读取推理结果Mat[] outs = new Mat[1] { new Mat() };string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();opencv_net.Forward(outs, outBlobNames);int num_proposal = outs[0].Size(1);int nout = outs[0].Size(2);float* pdata = (float*)outs[0].Data;List<float> confidences = new List<float>();List<Rect> boxes = new List<Rect>();List<int> classIds = new List<int>();for (int n = 0; n < num_stride; n++){int num_grid_x = (int)Math.Ceiling(inpWidth / strides[n]);int num_grid_y = (int)Math.Ceiling(inpHeight / strides[n]);for (int i = 0; i < num_grid_y; i++){for (int j = 0; j < num_grid_x; j++){float box_score = pdata[4];int max_ind = 0;float max_class_socre = 0;for (int k = 0; k < num_class; k++){if (pdata[k + 5] > max_class_socre){max_class_socre = pdata[k + 5];max_ind = k;}}max_class_socre = max_class_socre * box_score;max_class_socre = (float)Math.Sqrt(max_class_socre);if (max_class_socre > confThreshold){float cx = (0.5f + j + pdata[0]) * strides[n];  //cxfloat cy = (0.5f + i + pdata[1]) * strides[n];   //cyfloat w = (float)(Math.Exp(pdata[2]) * strides[n]);   //wfloat h = (float)(Math.Exp(pdata[3]) * strides[n]);  //hfloat xmin = (float)((cx - 0.5 * w) / ratio);float ymin = (float)((cy - 0.5 * h) / ratio);float xmax = (float)((cx + 0.5 * w) / ratio);float ymax = (float)((cy + 0.5 * h) / ratio);int left = (int)((cx - 0.5 * w) / ratio);int top = (int)((cy - 0.5 * h) / ratio);int width = (int)(w / ratio);int height = (int)(h / ratio);confidences.Add(max_class_socre);boxes.Add(new Rect(left, top, width, height));classIds.Add(max_ind);}pdata += nout;}}}int[] indices;CvDnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, out indices);for (int ii = 0; ii < indices.Length; ++ii){int idx = indices[ii];Rect box = boxes[idx];ltFace.Add(new Face(box, confidences[idx]));}outs[0].Dispose();BN_image.Dispose();dstimg.Dispose();return ltFace;}}
}

FaceQualityAssessment.cs

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System.Linq;namespace OpenCvSharp_DNN_Demo
{public class FaceQualityAssessment{Net net;int inpWidth = 112;int inpHeight = 112;float[] mean = new float[] { 0.5f, 0.5f, 0.5f };float[] std = new float[] { 0.5f, 0.5f, 0.5f };public FaceQualityAssessment(string modelpath){net = CvDnn.ReadNetFromOnnx(modelpath);}unsafe public float Detect(Mat cropped){Mat rgbimg = new Mat();Cv2.CvtColor(cropped, rgbimg, ColorConversionCodes.BGR2RGB);Cv2.Resize(rgbimg, rgbimg, new Size(inpWidth, inpHeight));Mat normalized_mat = Normalize(rgbimg);Mat blob = CvDnn.BlobFromImage(normalized_mat);//配置图片输入数据net.SetInput(blob);//模型推理,读取推理结果Mat[] outs = new Mat[1] { new Mat() };string[] outBlobNames = net.GetUnconnectedOutLayersNames().ToArray();net.Forward(outs, outBlobNames);float* pdata = (float*)outs[0].Data;  //形状1x10int length = outs[0].Size(1);float fqa_prob_mean = 0;for (int i = 0; i < length; i++){fqa_prob_mean += pdata[i];}fqa_prob_mean /= length;rgbimg.Dispose();normalized_mat.Dispose();blob.Dispose();outs[0].Dispose();return fqa_prob_mean;}Mat Normalize(Mat src){Mat[] bgr = src.Split();for (int i = 0; i < bgr.Length; ++i){bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 / (255.0 * std[i]), (0.0 - mean[i]) / std[i]);}Cv2.Merge(bgr, src);foreach (Mat channel in bgr){channel.Dispose();}return src;}}
}

下载

源码下载

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

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

相关文章

色标在matplotlib和plottable中

是这样的&#xff0c;我有一个数组[-4.4, -2.8, -2.6, -2.2, -1.1, 1.1, 1.2, 1.3, 3.6, 6.0, 6.4, 12.3]&#xff0c;它需要绘制散点图&#xff0c;点的颜色来代表数值大小&#xff1b;同时&#xff0c;也需要在plottable上作为一列显示&#xff0c;同样用颜色来代表数值的大小…

HarmonyOS应用开发学习笔记 ArkTS 布局概述

一、布局概述 布局指用特定的组件或者属性来管理用户页面所放置UI组件的大小和位置。在实际的开发过程中&#xff0c;需要遵守以下流程保证整体的布局效果 确定页面的布局结构。分析页面中的元素构成。选用适合的布局容器组件或属性控制页面中各个元素的位置和大小约束。 二…

【JUC】进程和线程

目录 &#x1f4e2;什么是进程?&#x1f3a1;什么是线程?&#x1f680;进程和线程的区别?&#x1f3a2;Java 线程和操作系统的线程有啥区别&#xff1f;&#x1f396;️JDK21的虚拟线程&#x1f3af;虚拟线程和平台线程的对比 &#x1f4e2;什么是进程? 进程是程序的一次执…

Zabbix“专家坐诊”第223期问答汇总

来源&#xff1a;乐维社区 问题一 Q&#xff1a;Zabbix 5.0安装完mysql之后怎么备份&#xff1f;忘记mysql当时创建的密码了&#xff0c;怎么样能查看设置的密码&#xff1f; A&#xff1a;mysql初始化密码在 /var/log/mysqld.log中可以看到&#xff0c;搜关键字temporary pas…

【算法分析与设计】移动零

题目 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 示例 2: 输入: nums [0…

电能计量芯片RN8209

电能计量芯片RN8209 简介2、操作2.1、复位2.2 模数转换2.3 有功功率2.4 无功功率2.5 有效值2.4 能量计算 RN8209中文手册 点击下载 简介 2、操作 2.1、复位 2.2 模数转换 2.3 有功功率 RN8209 提供两路有功功率的计算和校正&#xff0c;分别为电流 A 和电压有功功率计算和校正…

【笔记------freemodbus】一、stm32的裸机modbus-RTU从机移植(HAL库)

freemodbus的官方介绍和下载入口&#xff0c;官方仓库链接&#xff1a;https://github.com/cwalter-at/freemodbus modbus自己实现的话往往是有选择的支持几条指令&#xff0c;像断帧和异常处理可能是完全不处理的&#xff0c;用freemodbus实现的话要简单很多&#xff0c;可移植…

PR如何在一个视频里添加多个画面?多窗口画中画PR模板视频素材

Premiere Pro 2021模板&#xff0c;多窗口布局&#xff0c;多画面组合&#xff0c;小窗口视频&#xff0c;画中画视频效果制作素材PR模板mogrt文件。 4K、HD可调整到任何分辨率。 100多窗口布局样式。 来自PR模板网&#xff1a;https://prmuban.com/37059.html

深入了解pnpm:一种高效的包管理工具

✨专栏介绍 在当今数字化时代&#xff0c;Web应用程序已经成为了人们生活和工作中不可或缺的一部分。而要构建出令人印象深刻且功能强大的Web应用程序&#xff0c;就需要掌握一系列前端技术。前端技术涵盖了HTML、CSS和JavaScript等核心技术&#xff0c;以及各种框架、库和工具…

Unity | 渡鸦避难所-6 | 有限状态机控制角色行为逻辑

1 有限状态机简介 有限状态机&#xff08;英语&#xff1a;finite-state machine&#xff0c;缩写&#xff1a;FSM&#xff09;&#xff0c;简称状态机&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型 在游戏开发中应用有限状态机&#xff…

JavaWeb——后端之登录功能

6. 登录功能 6.1 登录认证 只进行用户名和密码是否存在的操作 Slf4j RestController public class LoginController {Autowiredpublic EmpService empService;PostMapping("/login")public Result login(RequestBody Emp emp) {log.info("{}员工登录", …

ASP .net core微服务实战

>>>>>>>>>>>>>>开发<<<<<<<<<<<<<<<< 0)用户 用户到nginx之间需要用https&#xff0c;避免被监听。 1)nginx // 做统一的分发&#xff0c;到微服务&#xff0c;相当于网关,提供统…

APP出海需知——Admob广告变现竞价策略

越来越多的出海公司更加重视应用的广告变现&#xff0c;Admob因其提供丰富的广告资源&#xff0c;稳定的平台支持&#xff0c;被广泛采用接入。 Admob广告变现策略 1、bidding竞价策略 Bidding目前是Admob广泛推广的较成熟的变现方案&#xff0c;当竞价网络和瀑布流混合时&a…

第二百五十四回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"如何给图片添加阴影"相关的内容&#xff0c;本章回中将介绍自定义Radio组件.闲话休提&#xff0c;让我们一起Talk Flutter吧…

JAVA:解析Event事件机制与应用举例

1、简述 Java事件机制是一种基于观察者模式的设计模式&#xff0c;用于处理对象之间的松耦合通信。本篇技术博客将深入探讨Java事件机制的原理&#xff0c;并通过实际应用举例展示如何在项目中灵活利用该机制。 2、基本原理 Java事件机制基于观察者模式&#xff0c;包含以下…

【AI视野·今日NLP 自然语言处理论文速览 第六十七期】Mon, 1 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Mon, 1 Jan 2024 Totally 42 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Principled Gradient-based Markov Chain Monte Carlo for Text Generation Authors Li Du, Afra Amini, Lucas…

npm i sass -D的含义

命令 npm i sass -D 是一个在Node.js项目中使用npm&#xff08;Node Package Manager&#xff09;安装Sass预处理器的命令。这个命令的各个部分含义如下&#xff1a; npm: 这是Node Package Manager的缩写&#xff0c;一个用于Node.js的包管理和分发工具&#xff0c;允许开发者…

手把手教你学会接口自动化系列二-编写一个get接口

之前我们写了登录接口,对于登录的接口是post请求。 详见: 手把手教你学会接口自动化系列一-浅浅地尝试编写登录接口的自动化代码-CSDN博客 我们都知道接口最常用的两种类型是get和post类型,为了让知识完整性,我这节课演示下接口自动化如何请求get类型的接口,因为get类型…

职场必备技能2自动化办公excel操作

目录 一、介绍excel 二、应用场景&#xff1a;----可以完成什么操作 生活中遇见的场景 三、下载 四、excel模块 3.1、xlrd 语法&#xff1a; 案例&#xff1a; 算2020年与2021收入差距是多少 3.2、openpyxl 语法 案例1&#xff1a;计算一年的工资--12个月 案例2&…

探讨JS混淆技术及其加密解密实例

引言 在当前计算机科学领域中&#xff0c;保护软件代码的安全性和隐私性变得愈发重要。为了防止黑客攻击和恶意软件分析&#xff0c;开发人员采用各种技术来混淆和加密其代码&#xff0c;其中包括JS混淆技术。本文将介绍JS混淆技术的原理和应用&#xff0c;并提供一些相关的加密…