C# DlibDotNet 人脸识别、人脸68特征点识别、人脸5特征点识别、人脸对齐,三角剖分,人脸特征比对

news2024/10/5 18:25:10

人脸识别


人脸68特征点识别

人脸5特征点识别


人脸对齐

三角剖分

人脸特征比对

项目

VS2022+.net4.8+OpenCvSharp4+DlibDotNet

Demo下载

代码

using DlibDotNet.Extensions;
using DlibDotNet;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using OpenCvSharp;
using System.Drawing.Imaging;
using System.Globalization;

namespace DlibDotNet_人脸识别_人脸68特征点识别_人脸5特征点识别
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string imgPath = "";
        string imgPath2 = "";
        string startupPath = "";


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

            pictureBox1.Image = null;

            imgPath = ofd.FileName;
            pictureBox1.Image = new Bitmap(imgPath);

        }

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

            pictureBox2.Image = null;

            imgPath2 = ofd.FileName;
            pictureBox2.Image = new Bitmap(imgPath2);

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string startupPath = Application.StartupPath;
            Dlib.Encoding = Environment.OSVersion.Platform == PlatformID.Win32NT ? Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.ANSICodePage) : Encoding.UTF8;

        }

        /// <summary>
        /// 人脸识别
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {

            if (imgPath == "")
            {
                return;
            }

            using (var faceDetector = Dlib.GetFrontalFaceDetector())
            using (var image = Dlib.LoadImage<RgbPixel>(imgPath))
            {
                var dets = faceDetector.Operator(image);
                foreach (var r in dets)
                    Dlib.DrawRectangle(image, r, new RgbPixel { Green = 255 });

                var result = image.ToBitmap();
                this.pictureBox1.Invoke(new Action(() =>
                {
                    this.pictureBox1.Image?.Dispose();
                    this.pictureBox1.Image = result;
                }));
            }

        }

        /// <summary>
        /// 5特征点识别
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            if (imgPath == "")
            {
                return;
            }

            string faceDataPath = "shape_predictor_5_face_landmarks.dat";

            Mat mat = new Mat(imgPath);

            Bitmap bmp = new Bitmap(imgPath);
            bmp = Get24bppRgb(bmp);

            // 图像转换到Dlib的图像类中
            Array2D<RgbPixel> img = DlibDotNet.Extensions.BitmapExtensions.ToArray2D<RgbPixel>(bmp);
            var faceDetector = Dlib.GetFrontalFaceDetector();
            var shapePredictor = ShapePredictor.Deserialize(faceDataPath);

            // 检测人脸
            var faces = faceDetector.Operator(img);

            if (faces.Count() == 0) { return; }

            // 人脸区域中识别脸部特征
            var shape = shapePredictor.Detect(img, faces[0]);

            var bradleyPoints = (from i in Enumerable.Range(0, (int)shape.Parts)
                                 let p = shape.GetPart((uint)i)
                                 select new OpenCvSharp.Point(p.X, p.Y)).ToArray();

            foreach (var item in bradleyPoints)
            {
                Cv2.Circle(mat, item.X, item.Y, 2, Scalar.Green, 2);
            }

            pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
        }

        // Convert to Format24bppRgb
        private static Bitmap Get24bppRgb(System.Drawing.Image image)
        {
            var bitmap = new Bitmap(image);
            var bitmap24 = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format24bppRgb);
            using (var gr = Graphics.FromImage(bitmap24))
            {
                gr.DrawImage(bitmap, new System.Drawing.Rectangle(0, 0, bitmap24.Width, bitmap24.Height));
            }
            return bitmap24;
        }

        /// <summary>
        /// 68特征点识别
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            if (imgPath == "")
            {
                return;
            }

            string faceDataPath = "shape_predictor_68_face_landmarks.dat";

            Mat mat = new Mat(imgPath);

            Bitmap bmp = new Bitmap(imgPath);
            bmp = Get24bppRgb(bmp);

            // 图像转换到Dlib的图像类中
            Array2D<RgbPixel> img = DlibDotNet.Extensions.BitmapExtensions.ToArray2D<RgbPixel>(bmp);
            var faceDetector = Dlib.GetFrontalFaceDetector();
            var shapePredictor = ShapePredictor.Deserialize(faceDataPath);

            // 检测人脸
            var faces = faceDetector.Operator(img);

            if (faces.Count() == 0) { return; }

            // 人脸区域中识别脸部特征
            var shape = shapePredictor.Detect(img, faces[0]);

            var bradleyPoints = (from i in Enumerable.Range(0, (int)shape.Parts)
                                 let p = shape.GetPart((uint)i)
                                 select new OpenCvSharp.Point(p.X, p.Y)).ToArray();

            foreach (var item in bradleyPoints)
            {
                Cv2.Circle(mat, item.X, item.Y, 2, Scalar.Green, 2);
            }

            pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
        }

        /// <summary>
        /// 人脸对齐
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            if (imgPath == "")
            {
                return;
            }
            var path = imgPath;
            string faceDataPath = "shape_predictor_68_face_landmarks.dat";
            using (var faceDetector = Dlib.GetFrontalFaceDetector())
            using (var img = Dlib.LoadImage<RgbPixel>(path))
            {
                Dlib.PyramidUp(img);
                var shapePredictor = ShapePredictor.Deserialize(faceDataPath);
                var dets = faceDetector.Operator(img);
                var shapes = new List<FullObjectDetection>();
                foreach (var rect in dets)
                {
                    var shape = shapePredictor.Detect(img, rect);
                    if (shape.Parts <= 2)
                        continue;
                    shapes.Add(shape);
                }

                if (shapes.Any())
                {
                    var lines = Dlib.RenderFaceDetections(shapes);
                    foreach (var line in lines)
                        Dlib.DrawLine(img, line.Point1, line.Point2, new RgbPixel
                        {
                            Green = 255
                        });

                    var wb = img.ToBitmap();
                    this.pictureBox1.Image?.Dispose();
                    this.pictureBox1.Image = wb;
                    foreach (var l in lines)
                        l.Dispose();
                    var chipLocations = Dlib.GetFaceChipDetails(shapes);
                    using (var faceChips = Dlib.ExtractImageChips<RgbPixel>(img, chipLocations))
                    using (var tileImage = Dlib.TileImages(faceChips))
                    {
                        // It is NOT necessary to re-convert WriteableBitmap to Matrix.
                        // This sample demonstrate converting managed image class to
                        // dlib class and vice versa.
                        using (var tile = tileImage.ToBitmap())
                        using (var mat = tile.ToMatrix<RgbPixel>())
                        {
                            var tile2 = mat.ToBitmap();
                            this.pictureBox1.Image?.Dispose();
                            this.pictureBox1.Image = tile2;
                        }
                    }

                    foreach (var c in chipLocations)
                        c.Dispose();
                }

                foreach (var s in shapes)
                    s.Dispose();
            }
        }

        /// <summary>
        /// 人脸特征比对
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";

            if (imgPath == "" || imgPath2 == "")
            {
                return;
            }

            var detector = Dlib.GetFrontalFaceDetector();
            var sp = ShapePredictor.Deserialize("shape_predictor_5_face_landmarks.dat");
            var net = DlibDotNet.Dnn.LossMetric.Deserialize("dlib_face_recognition_resnet_model_v1.dat");


            var img1 = Dlib.LoadImageAsMatrix<RgbPixel>(imgPath);
            var img2 = Dlib.LoadImageAsMatrix<RgbPixel>(imgPath2);

            var faces = new List<Matrix<RgbPixel>>();
            foreach (var face in detector.Operator(img1))
            {
                var shape = sp.Detect(img1, face);
                var faceChipDetail = Dlib.GetFaceChipDetails(shape, 150, 0.25);
                var faceChip = Dlib.ExtractImageChip<RgbPixel>(img1, faceChipDetail);
                faces.Add(faceChip);
            }

            foreach (var face in detector.Operator(img2))
            {
                var shape = sp.Detect(img2, face);
                var faceChipDetail = Dlib.GetFaceChipDetails(shape, 150, 0.25);
                var faceChip = Dlib.ExtractImageChip<RgbPixel>(img2, faceChipDetail);
                faces.Add(faceChip);
            }

            if (faces.Count != 2)
            {
                return;
            }

            var faceDescriptors = net.Operator(faces);

            // Faces are connected in the graph if they are close enough.  Here we check if
            // the distance between two face descriptors is less than 0.6, which is the
            // decision threshold the network was trained to use.  Although you can
            // certainly use any other threshold you find useful.
            var diff = faceDescriptors[1] - faceDescriptors[0];
            float len = Dlib.Length(diff);

            String str = "";
            if (len < 0.6)
            {
                str += "图片1和图片2距离:" + len.ToString() + "   是一个人" + "\r\n";
            }
            else
            {
                str += "图片1和图片2距离:" + len.ToString() + "   不是一个人" + "\r\n";
            }

            str += "图片1特征值:[" + faceDescriptors[0].ToString() + "]\r\n";
            str += "图片2特征值:[" + faceDescriptors[1].ToString() + "]\r\n";

            textBox1.Text = str;

        }

        /// <summary>
        /// 三角剖分
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button8_Click(object sender, EventArgs e)
        {

            if (imgPath == "")
            {
                return;
            }

            string faceDataPath = "shape_predictor_68_face_landmarks.dat";
            Mat mat = new Mat(imgPath);
            Bitmap bmp = new Bitmap(imgPath);
            bmp = Get24bppRgb(bmp);
            // 图像转换到Dlib的图像类中
            Array2D<RgbPixel> img = DlibDotNet.Extensions.BitmapExtensions.ToArray2D<RgbPixel>(bmp);
            var faceDetector = Dlib.GetFrontalFaceDetector();
            var shapePredictor = ShapePredictor.Deserialize(faceDataPath);
            // 检测人脸
            var faces = faceDetector.Operator(img);
            if (faces.Count() == 0)
            {
                return;
            }
            // 人脸区域中识别脸部特征
            var shape = shapePredictor.Detect(img, faces[0]);

            var bradleyPoints = (from i in Enumerable.Range(0, (int)shape.Parts)
                                 let p = shape.GetPart((uint)i)
                                 select new OpenCvSharp.Point(p.X, p.Y)).ToArray();

            pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);

            //凸包提取
            var hull = Cv2.ConvexHullIndices(bradleyPoints);
            var bradleyHull = (from i in hull
                               select bradleyPoints[i]).ToArray();

            for (int i = 0; i < bradleyHull.Length - 1; i++)
            {
                Cv2.Line(mat, bradleyHull[i].X, bradleyHull[i].Y, bradleyHull[i + 1].X, bradleyHull[i + 1].Y, Scalar.Red);
            }
            Cv2.Line(mat, bradleyHull[bradleyHull.Length - 1].X, bradleyHull[bradleyHull.Length - 1].Y, bradleyHull[0].X, bradleyHull[0].Y, Scalar.Red);

            pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);

            RotatedRect minAreaRect = Cv2.MinAreaRect(bradleyPoints);
            //三角剖分
            Subdiv2D subdiv = new Subdiv2D();
            Rect rect = new Rect(0, 0, pictureBox1.Image.Width, pictureBox1.Image.Height);
            subdiv.InitDelaunay(rect);

            // 添加与绘制特征点
            for (int i = 0; i < bradleyPoints.Length; i++)
            {
                subdiv.Insert(new Point2f(bradleyPoints[i].X, bradleyPoints[i].Y));
            }
            // 生成剖分三角形
            Vec6f[] triangleList = subdiv.GetTriangleList();
            OpenCvSharp.Point[] pt = new OpenCvSharp.Point[3];
            // 绘制剖分三角形
            for (int i = 0; i < triangleList.Length; i++)
            {
                Vec6f t = triangleList[i];
                pt[0] = new OpenCvSharp.Point((int)t[0], (int)t[1]);
                pt[1] = new OpenCvSharp.Point((int)t[2], (int)t[3]);
                pt[2] = new OpenCvSharp.Point((int)t[4], (int)t[5]);

                Cv2.Line(mat, pt[0], pt[1], Scalar.Green, 1);
                Cv2.Line(mat, pt[1], pt[2], Scalar.Green, 1);
                Cv2.Line(mat, pt[2], pt[1], Scalar.Green, 1);
            }

            pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);

        }
    }
}

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

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

相关文章

学堂在线数据结构(上)(2023春)邓俊辉 课后作业错题整理

The reverse number of a sequence is defined as the total number of reversed pairs in the sequence, and the total number of element comparisons performed by the insertion sort in the list of size n is: 一个序列的逆序数定义为该序列中的逆序对总数&#xff0c;…

transformer Position Embedding

这是最近一段很棒的 Youtube 视频&#xff0c;它深入介绍了位置嵌入&#xff0c;并带有精美的动画&#xff1a; Transformer 神经网络视觉指南 -&#xff08;第 1 部分&#xff09;位置嵌入 让我们尝试理解计算位置嵌入的公式的“sin”部分&#xff1a; 这里“pos”指的是“单词…

自定义view(一)----自定义TextView

自定义view也算是Android的一大难点&#xff0c;里面涉及到很多值得学习的地方&#xff0c;我会在接下来写一系列文章去介绍它&#xff0c;本篇文章以自定义一个TextView为例。 View的构造方法 自定义view之前我们先了解view的四个构造方法&#xff0c;自定义view无非就是新建一…

R语言逻辑回归(Logistic Regression)、回归决策树、随机森林信用卡违约分析信贷数据集...

原文链接&#xff1a;http://tecdat.cn/?p23344 本文中我们介绍了决策树和随机森林的概念&#xff0c;并在R语言中用逻辑回归、回归决策树、随机森林进行信用卡违约数据分析&#xff08;查看文末了解数据获取方式&#xff09;&#xff08;点击文末“阅读原文”获取完整代码数据…

MVSNet、PatchMatchNet中的 eval.sh文件超参数解释

下面以PatchMatchNet为例, 打开PatchMatchNet程序中的 eavl.sh文件, 可以看到文件设置了数据集路径,及超参数设置(超参数,也可以不写,会使用默认参数) 上图中各参数意思如下: 执行文件python eval.py; 数据集加载方方式使用dtu_yao_eval ; batch_size=1 ,视图数N设…

【C++】命名空间 ( namespace )

目录搁这 什么是命名空间命名空间的作用如何定义命名空间命名空间的种类如何使用命名空间内的成员作用域限定符命名空间展开命名空间全部展开命名空间部分展开 总结 什么是命名空间 命名空间是一种用来避免命名冲突的机制&#xff0c;它可以将一段代码的名称隔离开&#xff0c…

中国地图使用心得

中国地图使用心得 注册地图是注册在echarts对象上而非 自己构建的echarts dom上、。 请求本地json文件 ​ vue项目的public打包时不会动&#xff0c;所以线上和本地地址直接指向了public同级目录&#xff0c;请求时直接相对路径 绘制中国地图时&#xff0c;如何在各个省会地方…

「深度学习之优化算法」(十三)蝙蝠算法

1. 蝙蝠算法简介 (以下描述,均不是学术用语,仅供大家快乐的阅读)   蝙蝠算法(Bat Algorithm)是受蝙蝠回声定位的特性启发而提出的新兴算法,提出时间是2010年,虽然距今(2020)有近10年,但与其它的经典算法相比仍算一个新算法。算法也已有一定规模的研究和应用,但仍…

【LLM系列之LLaMA2】LLaMA 2技术细节详细介绍!

Llama 2 发布&#xff01; Meta 刚刚发布了 LLaMa 2&#xff0c;它是 LLaMA 的下一代版本&#xff0c;具有商业友好的许可证。&#x1f92f;&#x1f60d; LLaMA 2 有 3 种不同的尺寸&#xff1a;7B、13B 和 70B。 7B & 13B 使用与 LLaMA 1 相同的架构&#xff0c;并且是商…

年CTF—初五

0x00 前言 CTF 加解密合集&#xff1a;CTF 加解密合集 0x01 题目 神秘人送来了半个世纪前的无线电信号&#xff0c;但是只能分别出以下的密文&#xff1a; YDHML_QKA_PDK_HVD_NAHI_OQ_K_GR 据说上面的无线电信号代表的是中文&#xff0c;由红岸基地发往半人马星系 半个世纪过…

数据容器入门(set)

集合的定义&#xff1a; 语法&#xff1a;变量名称 {元素&#xff0c;元素&#xff0c;元素.........元素} 定义空集合&#xff1a; 变量名称 set&#xff08;&#xff09; set {“abc”&#xff0c;123&#xff0c;“def”} 集合的特点&#xff1a; 可以容纳多个数据可以容…

数据结构01-线性结构-链表栈队列-栈篇

文章目录 参考&#xff1a;总结大纲要求线性结构-栈回文匹配小猫钓鱼的故事 参考&#xff1a; 线性结构-栈 总结 本系列为C数据结构系列&#xff0c;会介绍 线性结构&#xff0c;简单树&#xff0c;特殊树&#xff0c;简单图等。本文为线性结构部分。 大纲要求 线性结构 【…

回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(不调用工具箱函数)

回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(不调用工具箱函数) 文章目录 回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(不调用工具箱函数)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 GRU神经网络是LSTM神经网络的一种变体&#xff0c;LSTM 神经网 …

集合面试题--二叉树,红黑树,散列表

目录 二叉树 二叉搜索树 时间复杂度 总结 红黑树 红黑树特质 复杂度 总结 散列表 散列函数 哈希冲突 散列冲突-链表法&#xff08;拉链&#xff09; 时间复杂度 ​总结 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是…

Mapbox GL JS学习之路(一):初识 Mapbox GL JS

文章目录 1 什么是Mapbox GL JS2 Mapbox GL JS 可以用来做什么2.1 在交互式地图上使用自己的数据自定义设计的地图样式2.2 商店定位器&#xff08;Store locator&#xff09;2.3 故事讲述&#xff08;Storytelling&#xff09;2.4 用于基于位置的数据可视化的仪表板&#xff08…

C++ deque/queue/stack的底层原理

deque容器的存储结构 和 vector 容器采用连续的线性空间不同&#xff0c;deque 容器存储数据的空间是由一段一段等长的连续空间构成&#xff0c;各段空间之间并不一定是连续的&#xff0c;可以位于在内存的不同区域。 deque采用一块所谓的map数组&#xff08;注意&#xff0c…

Lua 批量修改文件夹下文件名

local s io.popen("dir C:\\Users\\lizhiyuan\\Desktop\\国家知识产权局ftp法律状态数据\\data /b/s") local filelist s:read("*a")local start_pos 0while 1 do_,end_pos,line string.find(filelist, "([^\n\r].xml)", start_pos)if not e…

VScode 右键菜单加入使用用VSCode打开文件和文件夹【Windows】

VScode 右键菜单加入使用用VSCode打开文件和文件夹【Windows】 介绍修改注册表添加右键打开文件属性修改注册表添加右键打开文件夹属性修改注册表添加右键空白区域属性 介绍 鼠标右击文件或者文件夹&#xff0c;可直接用VSCode打开&#xff0c;非常方便。但如果我们在安装VSCo…

动态规划---子序列问题

一)最长递增子序列: 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 算法原理: 1.定义一个状态表示:经验题目要求 dp[i]表示&#xff0c;以i位置为结尾&#xff0c;最长递增子序列的长度 中心思路就是找到以i位置为结尾的所有递增子序列&#xff0c;然后找到递增…