【问题标题】:Face Recognition in C# (using EigenFaceRecognizer) recognizing an unknown face as a trained faceC# 中的人脸识别(使用 EigenFaceRecognizer)将未知人脸识别为经过训练的人脸
【发布时间】:2021-10-30 01:45:29
【问题描述】:

我试图在 C# 中使用“EigenFaceRecognizer”进行人脸识别。但问题是识别器将未知人脸识别为已知人脸。一旦识别器被训练来识别那张未知的脸,它就会正确地识别出那张脸。但它从不显示下面代码中所写的“未知”。

这是识别、捕捉、保存和训练人脸的完整代码:-

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Drawing;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Face;
using Emgu.CV.Structure;

namespace FaceRecognition
{
    class FaceRecognition:Form
    {
        private double distance = 50;
        private CascadeClassifier CascadeClassifier = new CascadeClassifier(Environment.CurrentDirectory + "/Resources/Haarcascade/haarcascade_frontalface_alt2.xml");
        private Image<Bgr, byte> Frame = (Image<Bgr, byte>)null;
        private Capture camera;
        private Mat mat = new Mat();
        private List<Image<Gray, byte>> trainedFaces = new List<Image<Gray, byte>>();
        private List<int> PersonLabs = new List<int>();
        private bool isEnable_SaveImage = false;
        private string ImageName;
        private PictureBox PictureBox_Frame;
        private PictureBox PictureBox_smallFrame;
        private string setPersonName;
        public bool isTrained = false;
        private List<string> Names = new List<string>();
        private EigenFaceRecognizer eigenFaceRecognizer;
        private IContainer components = (IContainer)null;
        private List<String> retNames = new List<string>();

        public FaceRecgnition()
        {
            this.InitializeComponent();
            if (Directory.Exists(Environment.CurrentDirectory + "\\Training_Data\\Faces\\Image"))
                return;
            Directory.CreateDirectory(Environment.CurrentDirectory + "\\Training_Data\\Faces\\Image");
        }

        public void getPersonName(Control control)
        {
            System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
            timer.Tick += new EventHandler(timer_getPersonName_Tick);
            timer.Interval = 100;
            timer.Start();

            void timer_getPersonName_Tick(object sender, EventArgs e) => control.Text = this.setPersonName;
        }

        public void openCamera(PictureBox pictureBox_Camera, PictureBox pictureBox_Trained)
        {
            this.PictureBox_Frame = pictureBox_Camera;
            this.PictureBox_smallFrame = pictureBox_Trained;
            this.camera = new Capture();
            this.camera.ImageGrabbed += new EventHandler(this.Camera_ImageGrabbed);
            this.camera.Start();
        }

        public void Save_IMAGE(string imageName)
        {
            this.ImageName = imageName;
            this.isEnable_SaveImage = true;
        }

        private void Camera_ImageGrabbed(object sender, EventArgs e)
        {
            this.camera.Retrieve((IOutputArray)this.mat, 0);
            this.Frame = this.mat.ToImage<Bgr, byte>(false).Resize(this.PictureBox_Frame.Width, this.PictureBox_Frame.Height, (Inter)2);

            this.detectFace();
            this.PictureBox_Frame.Image = (Image)this.Frame.Bitmap;
        }

        private void detectFace()
        {
            
            
            Image<Bgr, byte> resultImage = this.Frame.Convert<Bgr, byte>();
            Mat mat = new Mat();
            CvInvoke.CvtColor((IInputArray)this.Frame, (IOutputArray)mat, (ColorConversion)6, 0);
            CvInvoke.EqualizeHist((IInputArray)mat, (IOutputArray)mat);
            Rectangle[] rectangleArray = this.CascadeClassifier.DetectMultiScale((IInputArray)mat, 1.1, 4, new Size(), new Size());
            if ((uint)rectangleArray.Length > 0U)
            {
                foreach (Rectangle face in rectangleArray)
                {
                    Image<Bgr, byte> frame = this.Frame;
                    Rectangle rectangle = face;
                    Bgr bgr = new Bgr(Color.SpringGreen);
                    MCvScalar mcvScalar = ((Bgr)bgr).MCvScalar;
                    CvInvoke.Rectangle((IInputOutputArray)frame, rectangle, mcvScalar, 2, (LineType)8, 0);
                    this.SaveImage(face);
                    resultImage.ROI = face;
                    this.trainedIamge();
                    String name = this.CheckName(resultImage, face);
                    if (!retNames.Contains(name))
                    {
                        retNames.Add(name);
                    }
                }

            }
            else
            {
                this.setPersonName = "";
                retNames.Clear();

            }

        }

        private void SaveImage(Rectangle face)
        {
            if (!this.isEnable_SaveImage)
                return;
            Image<Bgr, byte> image = this.Frame.Convert<Bgr, byte>();
            image.ROI = face;
            Task.Factory.StartNew(() =>
            {
                for(int i = 0; i < 40; i++)
                {
                    ((CvArray<byte>)image.Resize(100, 100, (Inter)2)).Save(Environment.CurrentDirectory + "\\Training_Data\\Faces\\Image\\" + this.ImageName + "_" + DateTime.Now.ToString("dd-mm-yyyy-hh-mm-ss") + ".jpg");
                    Thread.Sleep(1000);
                    
                }
                
                
            });
            
            this.isEnable_SaveImage = false;
            this.trainedIamge();
        }

        private void trainedIamge()
        {
            try
            {
                int num = 0;
                this.trainedFaces.Clear();
                this.PersonLabs.Clear();
                this.Names.Clear();
                foreach (string file in Directory.GetFiles(Directory.GetCurrentDirectory() + "\\Training_Data\\Faces\\Image", "*.jpg", SearchOption.AllDirectories))
                {
                    
                    this.trainedFaces.Add(new Image<Gray, byte>(file));
                    this.PersonLabs.Add(num);
                    String name = file.Split('\\').Last().Split('_')[0];
                    this.Names.Add(name);
                    ++num;
                }
                this.eigenFaceRecognizer = new EigenFaceRecognizer(num, this.distance);
                ((FaceRecognizer)this.eigenFaceRecognizer).Train<Gray, byte>(this.trainedFaces.ToArray(), this.PersonLabs.ToArray());
            }
            catch
            {
            }
        }


        private string CheckName(Image<Bgr, byte> resultImage, Rectangle face)
        {
            retNames.Clear();
            try
            {
                if (!this.isTrained)
                    return null;
                Image<Gray, byte> image = resultImage.Convert<Gray, byte>().Resize(100, 100, (Inter)2);
                //);
                CvInvoke.EqualizeHist((IInputArray)image, (IOutputArray)image);
                //.Predict((IInputArray)image)
                FaceRecognizer.PredictionResult predictionResult = ((FaceRecognizer)this.eigenFaceRecognizer).Predict(image);
                if (predictionResult.Label != -1 && predictionResult.Distance < 5000)
                {
                    this.PictureBox_smallFrame.Image = (Image)this.trainedFaces[(int)predictionResult.Label].Bitmap;
                    this.setPersonName = this.Names[(int)predictionResult.Label].Replace(Environment.CurrentDirectory + "\\Training_Data\\Faces\\Image\\", "").Replace(".jpg", "");
                    Image<Bgr, byte> frame = this.Frame;
                    string setPersonName = this.setPersonName;
                    Point point = new Point(face.X - 2, face.Y - 2);
                    Bgr bgr = new Bgr(Color.Gold);
                    MCvScalar mcvScalar = ((Bgr)bgr).MCvScalar;
                    CvInvoke.PutText((IInputOutputArray)frame, setPersonName, point, (FontFace)1, 1.0, mcvScalar, 1, (LineType)8, false);
                    return setPersonName;
                }
                else
                {
                    Image<Bgr, byte> frame = this.Frame;
                    Point point = new Point(face.X - 2, face.Y - 2);
                    Bgr bgr = new Bgr(Color.OrangeRed);
                    MCvScalar mcvScalar = ((Bgr)bgr).MCvScalar;
                    CvInvoke.PutText((IInputOutputArray)frame, "Unknown", point, (FontFace)1, 1.0, mcvScalar, 1, (LineType)8, false);
                    return "Unknown";
                }
            }
            catch
            {
                return null;
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && this.components != null)
                this.components.Dispose();
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            this.AutoScaleDimensions = new SizeF(8f, 16f);
            this.AutoScaleMode = AutoScaleMode.Font;
            this.ClientSize = new Size(800, 450);
            this.Name = nameof(FaceRecognition);
            this.Text = nameof(FaceRecognition);
            this.ResumeLayout(false);
        }

        public List<String> getRetNames { get => retNames; }
        private String setRetNames { set => retNames.Add(value); }
    }
}

这是识别人脸的主要代码(如果你赶时间的话):-

private string CheckName(Image<Bgr, byte> resultImage, Rectangle face)
    {
        retNames.Clear();
        try
        {
            if (!this.isTrained)
                return null;
            Image<Gray, byte> image = resultImage.Convert<Gray, byte>().Resize(100, 100, (Inter)2);
         
            CvInvoke.EqualizeHist((IInputArray)image, (IOutputArray)image);

            FaceRecognizer.PredictionResult predictionResult = ((FaceRecognizer)this.eigenFaceRecognizer).Predict((IInputArray)image);
            if (predictionResult.Label != -1 && predictionResult.Distance < 5000)
            {
                this.PictureBox_smallFrame.Image = (Image)this.trainedFaces[(int)predictionResult.Label].Bitmap;
                this.setPersonName = this.Names[(int)predictionResult.Label].Replace(Environment.CurrentDirectory + "\\Training_Data\\Faces\\Image\\", "").Replace(".jpg", "");
                Image<Bgr, byte> frame = this.Frame;
                string setPersonName = this.setPersonName;
                Point point = new Point(face.X - 2, face.Y - 2);
                Bgr bgr = new Bgr(Color.Gold);
                MCvScalar mcvScalar = ((Bgr)bgr).MCvScalar;
                CvInvoke.PutText((IInputOutputArray)frame, setPersonName, point, (FontFace)1, 1.0, mcvScalar, 1, (LineType)8, false);
                return setPersonName;
            }
            else
            {
                Image<Bgr, byte> frame = this.Frame;
                Point point = new Point(face.X - 2, face.Y - 2);
                Bgr bgr = new Bgr(Color.OrangeRed);
                MCvScalar mcvScalar = ((Bgr)bgr).MCvScalar;
                CvInvoke.PutText((IInputOutputArray)frame, "Unknown", point, (FontFace)1, 1.0, mcvScalar, 1, (LineType)8, false);
                return "Unknown";
            }
        }
        catch
        {
            return null;
        }
    }

现在无论是哪张脸,--FaceRecognizer.PredictionResult predictionResult = ((FaceRecognizer)this.eigenFaceRecognizer).Predict((IInputArray)image); 总是返回predictionResult.Label = 0predictionResult.Distance = 0

我尝试了什么:-

  • 更改private double distance = 50;。最初是 1E+19,然后我将其设为 5000、2000,并使用许多不同的值对其进行了调整。
  • 使用所有 CascadeClassifier xml 文件。

但在我采取措施解决问题的所有情况下,predictionResult.LabelpredictionResult.Distance 的值始终为“0”。

P.S :- 这个问题可以是 1 或 2 个问题的重复,但在这些问题中,提问者既没有提供足够的信息,也没有答案。

【问题讨论】:

  • 还没有答案吗?奇怪....
  • 它是一个特定的库,它给您带来麻烦,因此没有答案,jet 并不少见。您是否尝试在开发者 github 上打开问题?
  • @lsparia 所以我的代码有什么问题吗?而且这个问题在库的开发人员支持之前无法解决?
  • 我第一眼看不到一个,但这并不意味着没有,因为我不熟悉这个库。由于这个问题的性质,我建议直接询问开发人员,因为他们更适合帮助您。

标签: c# .net face-recognition


【解决方案1】:

我遇到了一个类似的问题。为我解决的问题是确保

  1. 您的标签不包含零。 0 表示错误或类似情况。
  2. 获取公共图像数据集并在此基础上训练您的“未知”类型。 这就是我使用的:http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html

然后,Eigen 将在大多数情况下将未知面孔识别为未知。

【讨论】:

    猜你喜欢
    • 2017-08-29
    • 2014-06-04
    • 1970-01-01
    • 2019-10-30
    • 2011-12-14
    • 1970-01-01
    • 2015-01-06
    • 2014-03-24
    • 2011-06-06
    相关资源
    最近更新 更多