C# 离线人脸识别库 ViewFaceCore
ViewFaceCore 是一个使用 C# 开发的超简单的离线人脸识别库。( 基于 SeetaFace6 ),多平台支持, 开源、免费、跨平台 (win/linux)。
支持的 .NET 版本, .NET Framework, .NET Standard, .NET / .NET Core
简单的人脸信息检测
以 Windows x64平台 为例,一个简单的人脸检测Demo,需要先使用 nuget 安装依赖。
ViewFaceCore: .NET 核心库。
ViewFaceCore.all_models :人脸检测的模型支持(图省事可以直接安装这个)。
ViewFaceCore.runtime.win.x64 :Windows-x64 的本机运行时,其它平台自行选择安装,可安装多个。
ViewFaceCore.Extension.SkiaSharp:SkiaSharp图像处理扩展,ImageSharp、SkiaSharp、System.Drawing三选一。
.net 7 创建winform项目
简单画个窗体
主要引用nuget包
以下为源码
using ViewFaceCore.Core; using ViewFaceCore.Model; using ViewFaceCore; using SkiaSharp; using System.Drawing; using System.Diagnostics; namespace WinFormsApp { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png"; private void btnSelect_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = fileFilter; if (ofd.ShowDialog() != DialogResult.OK) return; pictureBox1.ImageLocation = ofd.FileName; label1.Text = pictureBox1.ImageLocation; } private void btnContrast_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = fileFilter; if (ofd.ShowDialog() != DialogResult.OK) return; pictureBox2.ImageLocation = ofd.FileName; label2.Text = pictureBox2.ImageLocation; } //人脸检测 private void button2_Click(object sender, EventArgs e) { string msg = ""; if (pictureBox1.Image == null) { msg = "图片1不能为空"; richTextBox1.Text += msg + "\r\n"; return; } using FaceDetector faceDetector = new FaceDetector(); using var bitmap = SKBitmap.Decode(pictureBox1.ImageLocation); FaceImage faceImage = bitmap.ToFaceImage(); FaceInfo[] infos = faceDetector.Detect(faceImage); if (infos.Length == 0) { msg = "图片1未检测到人脸"; richTextBox1.Text += msg + "\r\n"; return; } //Console.WriteLine("识别到的人脸数量:" + infos.Length + " 个人脸信息:\n"); //Console.WriteLine("No.\t人脸置信度\t位置信息"); //for (int i = 0; i < infos.Length; i++) //{ // Console.WriteLine(String.Format("{0}\t{1}\t{2}", i, infos[i].Score, infos[i].Location)); //} Bitmap bitmap2 = new Bitmap(pictureBox1.Image); //画方框,标记人脸 using (Graphics g = Graphics.FromImage(bitmap2)) { g.DrawRectangles(new Pen(Color.Red, 2), infos.Select(p => new RectangleF(p.Location.X, p.Location.Y, p.Location.Width, p.Location.Height)).ToArray()); } pictureBox1.Image = bitmap2; } //活体检测 private void button3_Click(object sender, EventArgs e) { string msg = ""; if (pictureBox1.Image == null) { msg = "图片1不能为空"; richTextBox1.Text += msg + "\r\n"; return; } using var bitmap = SKBitmap.Decode(pictureBox1.ImageLocation); //FaceImage bitmap = new Bitmap(pictureBox1.Image).ToFaceImage(); FaceDetector faceDetector = new FaceDetector(); FaceLandmarker faceMark = new FaceLandmarker(); FaceAntiSpoofing faceAntiSpoofing = new FaceAntiSpoofing(); if (faceDetector.Detect(bitmap).Length == 0) { msg = "图片1未检测到人脸"; richTextBox1.Text += msg + "\r\n"; return; } var info = faceDetector.Detect(bitmap).First(); var markPoints = faceMark.Mark(bitmap, info); Stopwatch sw = Stopwatch.StartNew(); sw.Start(); var result = faceAntiSpoofing.AntiSpoofing(bitmap, info, markPoints); msg = "活体检测,结果:" + result.Status + ",清晰度:" + result.Clarity + ",真实度:" + result.Reality + ",耗时:" + sw.ElapsedMilliseconds + "ms"; richTextBox1.Text += msg + "\r\n"; Console.WriteLine(msg); sw.Stop(); } //人脸比对 private void button9_Click(object sender, EventArgs e) { String msg = ""; if (pictureBox1.Image == null) { msg = "图片1不能为空"; richTextBox1.Text += msg + "\r\n"; return; } if (pictureBox2.Image == null) { msg = "图片2不能为空"; richTextBox1.Text += msg + "\r\n"; return; } Stopwatch sw = Stopwatch.StartNew(); sw.Start(); using var faceImage0 = SKBitmap.Decode(pictureBox1.ImageLocation); using var faceImage1 = SKBitmap.Decode(pictureBox2.ImageLocation); //检测人脸信息 FaceDetector faceDetector = new FaceDetector(); FaceInfo[] infos0 = faceDetector.Detect(faceImage0); FaceInfo[] infos1 = faceDetector.Detect(faceImage1); if (infos0.Length == 0) { msg = "图片1未检测到人脸"; richTextBox1.Text += msg + "\r\n"; sw.Stop(); return; } if (infos1.Length == 0) { msg = "图片2未检测到人脸"; richTextBox1.Text += msg + "\r\n"; sw.Stop(); return; } //标记人脸位置 FaceLandmarker faceMark = new FaceLandmarker(); FaceMarkPoint[] points0 = faceMark.Mark(faceImage0, infos0[0]); FaceMarkPoint[] points1 = faceMark.Mark(faceImage1, infos1[0]); //提取特征值 FaceRecognizer faceRecognizer = new FaceRecognizer(); float[] data0 = faceRecognizer.Extract(faceImage0, points0); float[] data1 = faceRecognizer.Extract(faceImage1, points1); //对比特征值 bool isSelf = faceRecognizer.IsSelf(data0, data1); //计算相似度 float similarity = faceRecognizer.Compare(data0, data1); msg = "识别到的人脸是否为同一人:" + isSelf + ",相似度:" + similarity + ",对比耗时:" + sw.ElapsedMilliseconds + "ms"; richTextBox1.Text += msg + "\r\n"; Console.WriteLine(msg); sw.Stop(); } //口罩检测 private void button4_Click(object sender, EventArgs e) { string msg = ""; if (pictureBox1.Image == null) { msg = "图片1不能为空"; richTextBox1.Text += msg + "\r\n"; return; } FaceImage bitmap = SKBitmap.Decode(pictureBox1.ImageLocation).ToFaceImage(); FaceDetector faceDetector = new FaceDetector(); MaskDetector maskDetector = new MaskDetector(); if (faceDetector.Detect(bitmap).Length == 0) { msg = "图片1未检测到人脸"; richTextBox1.Text += msg + "\r\n"; return; } var info = faceDetector.Detect(bitmap).First(); PlotMaskResult plotMaskResult = maskDetector.PlotMask(bitmap, info); if (plotMaskResult.Masked) { richTextBox1.Text += "口罩:是 \r\n"; } else { richTextBox1.Text += "口罩:否 \r\n"; } Console.WriteLine(msg); } //年龄预测 private void button5_Click(object sender, EventArgs e) { string msg = ""; if (pictureBox1.Image == null) { msg = "图片1不能为空"; richTextBox1.Text += msg + "\r\n"; return; } FaceImage bitmap = SKBitmap.Decode(pictureBox1.ImageLocation).ToFaceImage(); FaceDetector faceDetector = new FaceDetector(); if (faceDetector.Detect(bitmap).Length == 0) { msg = "图片1未检测到人脸"; richTextBox1.Text += msg + "\r\n"; return; } var info = faceDetector.Detect(bitmap).First(); AgePredictor agePredictor = new AgePredictor(); FaceLandmarker faceMark = new FaceLandmarker(); var markPoints = faceMark.Mark(bitmap, info); int age = agePredictor.PredictAge(bitmap, markPoints); richTextBox1.Text += "年龄:" + age + " \r\n"; Console.WriteLine(msg); } //性别预测 private void button6_Click(object sender, EventArgs e) { string msg = ""; if (pictureBox1.Image == null) { msg = "图片1不能为空"; richTextBox1.Text += msg + "\r\n"; return; } FaceImage bitmap = SKBitmap.Decode(pictureBox1.ImageLocation).ToFaceImage(); FaceDetector faceDetector = new FaceDetector(); if (faceDetector.Detect(bitmap).Length == 0) { msg = "图片1未检测到人脸"; richTextBox1.Text += msg + "\r\n"; return; } var info = faceDetector.Detect(bitmap).First(); GenderPredictor genderPredictor = new GenderPredictor(); FaceLandmarker faceMark = new FaceLandmarker(); var markPoints = faceMark.Mark(bitmap, info); Gender gender = genderPredictor.PredictGender(bitmap, markPoints); richTextBox1.Text += "性别:" + gender + " \r\n"; Console.WriteLine(msg); } //眼睛状态 private void button7_Click(object sender, EventArgs e) { string msg = ""; if (pictureBox1.Image == null) { msg = "图片1不能为空"; richTextBox1.Text += msg + "\r\n"; return; } FaceImage bitmap = SKBitmap.Decode(pictureBox1.ImageLocation).ToFaceImage(); FaceDetector faceDetector = new FaceDetector(); if (faceDetector.Detect(bitmap).Length == 0) { msg = "图片1未检测到人脸"; richTextBox1.Text += msg + "\r\n"; return; } var info = faceDetector.Detect(bitmap).First(); EyeStateDetector eyeStateDetector = new EyeStateDetector(); FaceLandmarker faceMark = new FaceLandmarker(); var markPoints = faceMark.Mark(bitmap, info); EyeStateResult eyeStateResult = eyeStateDetector.Detect(bitmap, markPoints); richTextBox1.Text += "眼睛状态:" + eyeStateResult + " \r\n"; Console.WriteLine(msg); } } }
运行结果 :
人脸检测:
活体检测:
人脸检测: