C# OpenCvSharp DNN FreeYOLO 人脸检测

news2024/11/16 5:40:52

目录

效果

模型信息

项目

代码

下载


C# OpenCvSharp DNN FreeYOLO 人脸检测

效果

模型信息

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

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

项目

代码

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
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;

        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;
        Mat result_image;

        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)
        {
            confThreshold = 0.8f;
            nmsThreshold = 0.5f;

            modelpath = "model/yolo_free_huge_widerface_192x320.onnx";

            inpHeight = 192;
            inpWidth = 320;

            opencv_net = CvDnn.ReadNetFromOnnx(modelpath);

            class_names = new List<string>();
            class_names.Add("face");
            num_class = 1;

            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 = "检测中,请稍等……";
            pictureBox2.Image = null;
            Application.DoEvents();

            image = new Mat(image_path);

            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();

            dt1 = DateTime.Now;

            opencv_net.Forward(outs, outBlobNames);

            dt2 = DateTime.Now;

            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];  //cx
                            float cy = (0.5f + i + pdata[1]) * strides[n];   //cy
                            float w = (float)(Math.Exp(pdata[2]) * strides[n]);   //w
                            float h = (float)(Math.Exp(pdata[3]) * strides[n]);  //h

                            float 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);

            result_image = image.Clone();

            for (int ii = 0; ii < indices.Length; ++ii)
            {
                int idx = indices[ii];
                Rect box = boxes[idx];
                Cv2.Rectangle(result_image, new OpenCvSharp.Point(box.X, box.Y), new OpenCvSharp.Point(box.X + box.Width, box.Y + box.Height), new Scalar(0, 0, 255), 2);
                string label = class_names[classIds[idx]] + ":" + confidences[idx].ToString("0.00");
                Cv2.PutText(result_image, label, new OpenCvSharp.Point(box.X, box.Y - 5), HersheyFonts.HersheySimplex, 1, new Scalar(0, 0, 255), 2);
            }

            pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
            textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";

        }

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

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

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
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;

        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;
        Mat result_image;

        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)
        {
            confThreshold = 0.8f;
            nmsThreshold = 0.5f;

            modelpath = "model/yolo_free_huge_widerface_192x320.onnx";

            inpHeight = 192;
            inpWidth = 320;

            opencv_net = CvDnn.ReadNetFromOnnx(modelpath);

            class_names = new List<string>();
            class_names.Add("face");
            num_class = 1;

            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 = "检测中,请稍等……";
            pictureBox2.Image = null;
            Application.DoEvents();

            image = new Mat(image_path);

            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();

            dt1 = DateTime.Now;

            opencv_net.Forward(outs, outBlobNames);

            dt2 = DateTime.Now;

            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];  //cx
                            float cy = (0.5f + i + pdata[1]) * strides[n];   //cy
                            float w = (float)(Math.Exp(pdata[2]) * strides[n]);   //w
                            float h = (float)(Math.Exp(pdata[3]) * strides[n]);  //h

                            float 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);

            result_image = image.Clone();

            for (int ii = 0; ii < indices.Length; ++ii)
            {
                int idx = indices[ii];
                Rect box = boxes[idx];
                Cv2.Rectangle(result_image, new OpenCvSharp.Point(box.X, box.Y), new OpenCvSharp.Point(box.X + box.Width, box.Y + box.Height), new Scalar(0, 0, 255), 2);
                string label = class_names[classIds[idx]] + ":" + confidences[idx].ToString("0.00");
                Cv2.PutText(result_image, label, new OpenCvSharp.Point(box.X, box.Y - 5), HersheyFonts.HersheySimplex, 1, new Scalar(0, 0, 255), 2);
            }

            pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
            textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";

        }

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

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

下载

可运行程序exe下载

源码下载

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

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

相关文章

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑多元不确定性和备用需求的微电网双层鲁棒容量规划》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 这个标题涉及微电网&#xff08;Microgrid&#xff09;的双层鲁棒容量规划&#xff0c;考虑了多元不确定性和备用需求。让我们逐步解读这个标题&#xf…

【AI视野·今日NLP 自然语言处理论文速览 第六十六期】Tue, 31 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Tue, 31 Oct 2023 (showing first 100 of 141 entries) Totally 100 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers The Eval4NLP 2023 Shared Task on Prompting Large Language Models a…

箭头函数 - JavaScript的新宠儿

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…

C++——STL标准模板库——容器详解——stack+queue

一、基本概念 &#xff08;一&#xff09;stack&#xff08;栈或堆栈&#xff09; 一种只允许同一端进出的线性数据结构&#xff0c;数据先进后出。基本模型类似于瓶子。 &#xff08;二&#xff09;queue&#xff08;队列&#xff09; 一种只允许一端进、另一端出的线性数…

UE5.1_UMG序列帧动画制作

UE5.1_UMG序列帧动画制作 UMG序列帧动画制作相对比较简单&#xff0c;不像视频帧需要创建媒体播放器那么复杂&#xff0c;以下简要说明&#xff1a; 1. 事件函数 2. 准备序列帧装入数组 3. 构造调用事件函数 4. 预览 序列帧UMG0105 5. 完成&#xff01;按需配置即可。

本地引入Element UI后导致图标显示异常

引入方式 npm 安装 推荐使用 npm 的方式安装&#xff0c;它能更好地和 webpack 打包工具配合使用。 npm i element-ui -SCDN 目前可以通过 unpkg.com/element-ui 获取到最新版本的资源&#xff0c;在页面上引入 js 和 css 文件即可开始使用。 <!-- 引入样式 --> <…

面试题-DAG 有向无环图

有向无环图用于解决前后依赖问题&#xff0c;在Apollo中用于各个组件的依赖管理。 在算法面试中&#xff0c;有很多相关题目 比如排课问题&#xff0c;有先修课比如启动问题&#xff0c;需要先启动1&#xff0c;才能启动2 概念 顶点&#xff1a; 图中的一个点&#xff0c;比…

scratch绘制小正方形 2023年12月中国电子学会图形化编程 少儿编程 scratch编程等级考试四级真题和答案解析

目录 scratch绘制小正方形 一、题目要求 1、准备工作 2、功能实现 二、案例分析

揭开 JavaScript 作用域的神秘面纱(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

第11章 GUI Page462~476 步骤二十三 步骤二十四 Undo/Redo ②“添加操作”支持“Undo/Redo”

工程二 1.为AddAction类添加Undo() Redo() GetName()成员函数 2.实现AddAction类的Undo() Redo()函数 3.运行效果&#xff0c;但是日志窗口没有记录 原因&#xff1a;AddAction(EditAction* newAction)函数没有实现&#xff0c;另外参数是EditAction类型 所以我们还需要在基…

C# .Net学习笔记—— 异步和多线程(await/async)

一、介绍 1、控制台测试await/async 2、C# 5.0 .Net framework4.5 CLR4.0 以后才有&#xff0c;本身是一种语法糖 二、基本测试 1、不加await测试。 private async static Task TestAsync() {Log.Info($"当前主线程id{Thread.CurrentThread.ManagedThreadId}"…

简易视频播放器(案例)

介绍 本篇Codelab使用ArkTS语言实现视频播放器&#xff0c;主要包括主界面和视频播放界面&#xff0c;我们将一起完成以下功能&#xff1a; 主界面顶部使用Swiper组件实现视频海报轮播。主界面下方使用List组件实现视频列表。播放界面使用Video组件实现视频播放。在不使用视频组…

在Uniapp中使用Echarts创建可视化图表

在uniapp中可以引入echarts创建数据可视化图表。 1. 安装Echarts 使用npm安装echarts插件&#xff0c;命令如下&#xff1a; npm install echarts --save2. 引入Eharts 在需要使用Echarts的页面引入&#xff1a; import *as echarts from echarts3. 创建实例 创建画布元素…

基于单片机的农田灌溉系统(论文+源码)

1.系统设计 本系统主要实现如下目标&#xff1a; 1&#xff0e;可以实时监测土壤湿度&#xff1b; 2&#xff0e;土壤湿度太低时&#xff0c;进行浇水操作&#xff1b; 3&#xff0e;可以按键设置湿度的触发阈值&#xff1b; 4. 可以实现远程操控 5&#xff0e;可以实现手…

基于 ESP32-C3 开启 Flash 加密和安全启动并进行 OTA 测试

软件&#xff1a; esp-idf v5.1.2 硬件&#xff1a; ESP32-C3 board 1. 首先&#xff0c;准备一个明文固件 hello-world.bin 基于 esp-idf-v5.1.2\examples\get-started\hello_world 例程&#xff0c;使用如下指令&#xff0c;直接编译&#xff0c;获取明文固件 hello-worl…

【软考中级-软件设计师】day1:CPU、数据的表示、校验码

考点分布目录 中央处理单元CPU 练习题 数据的表示 二进制转十进制 练习题 十进制转二进制 练习题 原码 练习题 反码 练习题 补码 练习题 练习题 移码 浮点数 练习题 奇偶校验 练习题 校验码 模2除法 循环冗余校验CRC 练习题 练习题 练习题 奇偶校验码 只…

【读书】《白帽子讲web安全》个人笔记Ⅰ-1

目录 前言&#xff1a; 第1章 我的安全世界观 1.1 Web安全简史 1.1.1中国黑客简史 1.1.2黑客技术的发展历程 1.1.3web安全的兴起 1.2黑帽子&#xff0c;白帽子 1.3返璞归真&#xff0c;揭秘安全的本质 1.4破除迷信&#xff0c;没有银弹 1.5安全三要素 1.6如何实施安…

​结构体数组

1. 结构体的声明 1.1 结构体的基础知识 结构是一些值的集合&#xff0c;这些值被称为成员变量。结构的每个成员可以是不同类型的变量。 1.2 结构的声明 struct tag {member - list; }variable-list; 例&#xff1a;描述一个人的信息&#xff1a;名字电话性别身高 //声明的…

Vue2 - computed 和 method 的原理区别

目录 1&#xff0c;简单对比2&#xff0c;原理的不同1&#xff0c;method 的处理2&#xff0c;computed 的处理实现缓存触发更新 3&#xff0c;触发更新时的问题 1&#xff0c;简单对比 computed 当做属性使用&#xff0c;method 当做方法使用。computed 可以提供 getter 和 s…

DS|图(连通与生成树)

题目一&#xff1a;DS图 -- 图的连通分量 题目描述&#xff1a; 输入无向图顶点信息和边信息&#xff0c;创建图的邻接矩阵存储结构&#xff0c;计算图的连通分量个数。 输入要求&#xff1a; 测试次数t 每组测试数据格式如下&#xff1a; 第一行&#xff1a;顶点数 顶点…