【问题标题】:Emgu CV EigenObjectRecognizer not workingEmgu CV EigenObjectRecognizer 不工作
【发布时间】:2012-07-15 01:47:31
【问题描述】:

我尝试编写人脸识别程序,需要社区的帮助。 下面发布的代码编译没有错误,但识别器似乎不起作用? 基本上 target.jpg 包含一个从 pic1.jpg 中裁剪出来的人(里面有 3 个人),所以识别器应该能够更容易地检测到它。

下面的代码运行没有错误,但是 pic1.jpg 中的所有 3 个人都被装箱了,所有 3 个面孔的 GetEigenDistances 都是 0。正确地只有 pic1.jpg 中的人(目标.jpg 中的人)应该被装箱.

知道我哪里出错了吗?提前致谢。

我正在使用带有 c# 2010 express 的 emgu cv 2.4

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Emgu.CV.CvEnum;


namespace FaceReco
{
    public partial class Form1 : Form
    {
        private HaarCascade haar;
        List<Image<Gray, byte>> trainingImages = new List<Image<Gray, byte>>();
        Image<Gray, byte> TrainedFace, UnknownFace = null;
        MCvFont font = new MCvFont(FONT.CV_FONT_HERSHEY_TRIPLEX, 0.5d, 0.5d);


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // adjust path to find your XML file 
            haar = new HaarCascade("haarcascade_frontalface_alt_tree.xml");

            //Read an target image
            Image TargetImg = Image.FromFile(Environment.CurrentDirectory + "\\target\\target.jpg");
            Image<Bgr, byte> TargetFrame = new Image<Bgr, byte>(new Bitmap(TargetImg));

            //FACE DETECTION FOR TARGET FACE
            if (TargetImg != null)   // confirm that image is valid
            {
                //convert the image to gray scale
                Image<Gray, byte> grayframe = TargetFrame.Convert<Gray, byte>();
                var faces = grayframe.DetectHaarCascade(haar, 1.4, 4,
                                        HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
                                        new Size(25, 25))[0];
                foreach (var face in faces)
                {
                    //add into training array
                    TrainedFace = TargetFrame.Copy(face.rect).Convert<Gray, byte>().Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
                    trainingImages.Add(TrainedFace);
                    break;
                }
                TargetImageBox.Image = TrainedFace;
            }


            //Read an unknown image
            Image UnknownImg = Image.FromFile(Environment.CurrentDirectory + "\\img\\pic1.jpg");
            Image<Bgr, byte> UnknownFrame = new Image<Bgr, byte>(new Bitmap(UnknownImg));

            //FACE DETECTION PROCESS
            if (UnknownFrame != null)   // confirm that image is valid
            {
                //convert the image to gray scale
                Image<Gray, byte> grayframe = UnknownFrame.Convert<Gray, byte>();

                //Detect faces from the gray-scale image and store into an array of type 'var',i.e 'MCvAvgComp[]'
                var faces = grayframe.DetectHaarCascade(haar, 1.4, 4,
                                        HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
                                        new Size(25, 25))[0];

                //draw a green rectangle on each detected face in image
                foreach (var face in faces)
                {
                    UnknownFace = UnknownFrame.Copy(face.rect).Convert<Gray, byte>().Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
                    MCvTermCriteria termCrit = new MCvTermCriteria(16, 0.001);
                    //Eigen face recognizer
                    EigenObjectRecognizer recognizer = new EigenObjectRecognizer(trainingImages.ToArray(), ref termCrit);

                    // if recognise face, draw green box
                    if (recognizer.Recognize(UnknownFace) != null)
                    {
                        UnknownFrame.Draw(face.rect, new Bgr(Color.Green), 3);
                    }

                    float f = recognizer.GetEigenDistances(UnknownFace)[0];
                    // display threshold
                    UnknownFrame.Draw(f.ToString("R"), ref font, new Point(face.rect.X - 3, face.rect.Y - 3), new Bgr(Color.Red));

                }

                //Display the image
                CamImageBox.Image = UnknownFrame;
            }
        }
    }
}

【问题讨论】:

    标签: c# face-recognition emgucv


    【解决方案1】:

    这个领域还不是我的专长,但如果我能提供帮助,我会尝试。这就是我正在使用的,而且效果很好。

    尝试使用 GPU 完成所有工作,它比 CPU 快得多!

    List<Rectangle> faces = new List<Rectangle>();
    
    List<Rectangle> eyes = new List<Rectangle>();
    
    RightCameraImage = RightCameraImageCapture.QueryFrame().Resize(480, 360, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC); //Read the files as an 8-bit Bgr image
    
    //Emgu.CV.GPU.GpuInvoke.HasCuda
    if (GpuInvoke.HasCuda)
    {
    Video.DetectFace.UsingGPU(RightCameraImage, Main.FaceGpuCascadeClassifier, Main.EyeGpuCascadeClassifier, faces, eyes, out detectionTime);
    }
    else
    {
    Video.DetectFace.UsingCPU(RightCameraImage, Main.FaceCascadeClassifier, Main.EyeCascadeClassifier, faces, eyes, out detectionTime);
    }
    
    string PersonsName = string.Empty;
    
    Image<Gray, byte> GreyScaleFaceImage;
    
    foreach (Rectangle face in faces)
    {
    RightCameraImage.Draw(face, new Bgr(Color.Red), 2);
    
    GreyScaleFaceImage = RightCameraImage.Copy(face).Convert<Gray, byte>().Resize(200, 200, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
    
    if (KnownFacesList.Count > 0)
    {
    // MCvTermCriteria for face recognition...
    MCvTermCriteria mCvTermCriteria = new MCvTermCriteria(KnownFacesList.Count, 0.001);
    
    // Recognize Known Faces with Eigen Object Recognizer...
    EigenObjectRecognizer recognizer = new EigenObjectRecognizer(KnownFacesList.ToArray(), KnownNamesList.ToArray(), eigenDistanceThreashhold, ref mCvTermCriteria);
    
    EigenObjectRecognizer.RecognitionResult recognitionResult = recognizer.Recognize(GreyScaleFaceImage);
    
    if (recognitionResult != null)
    {
    // Set the Persons Name...
    PersonsName = recognitionResult.Label;
    
    // Draw the label for each face detected and recognized...
    RightCameraImage.Draw(PersonsName, ref mCvFont, new Point(face.X - 2, face.Y - 2), new Bgr(Color.LightGreen));
    }
    else
    {
    // Draw the label for each face NOT Detected...
    RightCameraImage.Draw(FaceUnknown, ref mCvFont, new Point(face.X - 2, face.Y - 2), new Bgr(Color.LightGreen));
    }
    }
    }
    

    我在课堂上的代码:Video.DetectFace:

    using System;
    using Emgu.CV;
    using Emgu.CV.GPU;
    using System.Drawing;
    using Emgu.CV.Structure;
    using System.Diagnostics;
    using System.Collections.Generic;
    
    namespace Video
    {
    //-----------------------------------------------------------------------------------
    //  Copyright (C) 2004-2012 by EMGU. All rights reserved. Modified by Chris Sykes. 
    //-----------------------------------------------------------------------------------
    
    public static class DetectFace
    {
    // Use me like this:
    /*
    //Emgu.CV.GPU.GpuInvoke.HasCuda
    if (GpuInvoke.HasCuda)
    {
    DetectUsingGPU(...);
    }
    else
    {
    DetectUsingCPU(...);
    }
    */
    
    private static Stopwatch watch;
    
    public static void UsingGPU(Image<Bgr, Byte> image, GpuCascadeClassifier face, GpuCascadeClassifier eye, List<Rectangle> faces, List<Rectangle> eyes, out long detectionTime)
    {
    watch = Stopwatch.StartNew();
    
    using (GpuImage<Bgr, Byte> gpuImage = new GpuImage<Bgr, byte>(image))
    using (GpuImage<Gray, Byte> gpuGray = gpuImage.Convert<Gray, Byte>())
    {
    Rectangle[] faceRegion = face.DetectMultiScale(gpuGray, 1.1, 10, Size.Empty);
    faces.AddRange(faceRegion);
    foreach (Rectangle f in faceRegion)
    {
    using (GpuImage<Gray, Byte> faceImg = gpuGray.GetSubRect(f))
    {
    //For some reason a clone is required.
    //Might be a bug of GpuCascadeClassifier in opencv
    using (GpuImage<Gray, Byte> clone = faceImg.Clone())
    {
    Rectangle[] eyeRegion = eye.DetectMultiScale(clone, 1.1, 10, Size.Empty);
    
    foreach (Rectangle e in eyeRegion)
    {
    Rectangle eyeRect = e;
    eyeRect.Offset(f.X, f.Y);
    eyes.Add(eyeRect);
    }
    }
    }
    }
    }
    watch.Stop();
    detectionTime = watch.ElapsedMilliseconds;
    }
    public static void UsingCPU(Image<Bgr, Byte> image, CascadeClassifier face, CascadeClassifier eye, List<Rectangle> faces, List<Rectangle> eyes, out long detectionTime)
    {
    watch = Stopwatch.StartNew();
    using (Image<Gray, Byte> gray = image.Convert<Gray, Byte>()) //Convert it to Grayscale
    {
    //normalizes brightness and increases contrast of the image
    gray._EqualizeHist();
    
    //Detect the faces  from the gray scale image and store the locations as rectangle
    //The first dimensional is the channel
    //The second dimension is the index of the rectangle in the specific channel
    Rectangle[] facesDetected = face.DetectMultiScale(gray, 1.1, 10, new Size(20, 20), Size.Empty);
    faces.AddRange(facesDetected);
    
    foreach (Rectangle f in facesDetected)
    {
    //Set the region of interest on the faces
    gray.ROI = f;
    Rectangle[] eyesDetected = eye.DetectMultiScale(gray, 1.1, 10, new Size(20, 20), Size.Empty);
    gray.ROI = Rectangle.Empty;
    
    foreach (Rectangle e in eyesDetected)
    {
    Rectangle eyeRect = e;
    eyeRect.Offset(f.X, f.Y);
    eyes.Add(eyeRect);
    }
    }
    }
    watch.Stop();
    detectionTime = watch.ElapsedMilliseconds;
    }
    } // END of CLASS...
    }// END of NAMESPACE...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-22
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-10
      相关资源
      最近更新 更多