人脸识别使用EigenObjectRecognizer

时间:2014-03-11 14:56:08

标签: opencv image-processing computer-vision emgucv face-recognition

我对EMGUCV很新。我想制作一个人脸识别系统,我已经实现了,但结果是不可接受的。这是我的识别代码:

public List<Person> RecognizeFaces(List<Image<Bgr, byte>> faces)
{
        List<Person> RecognizedPersons = new List<Person>();
        MCvTermCriteria termCrit = new MCvTermCriteria(TrainDB.Count, 0.001);

        EigenObjectRecognizer recognizer = new EigenObjectRecognizer(
         this.ToGrayList(this.TrainDB),
         labels.ToArray(),
         7000,  // I changed this argument many times but nothing has changed (1000, 2000, ...
         ref termCrit);

        string label = "";
        for (int i = 0; i < faces.Count; i++)
        {
            label = recognizer.Recognize(faces[i].Convert<Gray, byte>());
            RecognizedPersons.Add(new Person(faces[i],!label.Equals("") ? label : "unknown"));
        }

        return RecognizedPersons;
}

此功能从输入图像中获取先前检测到的面部列表,并返回类型Person的列表,其中每个人都包含图像和标签给识别的人。 我的问题是为什么结果不好?我的代码有问题吗?或者训练集TrainDB有问题,如果是这样,创建训练集时要遵循的最佳指导原则是什么?

我根据这个收集了训练集: 1-在包含单个人的图像上应用面部检测(使用EMGU) 2-然后我将检测到的面部调整为200:W,200:H

我的训练集中的一些图像:

enter image description here

enter image description here

测试图像的一些示例:

enter image description here

  • 列表项

enter image description here

enter image description here

我的上一个问题.. Emgu / OpenCv是否是用于人脸识别的强大工具?或者还有其他一些可以更准确的结果?

2 个答案:

答案 0 :(得分:1)

您的训练集应具有相同的尺寸(尺寸)和灰色图像

List<Image<Gray, byte>>

答案 1 :(得分:0)

您能告诉我们您要检测的面部捕获方法吗?您只是给它位图并要求它识别吗?您需要做的是首先进行面部检测,您可以使用相同的库,例如:

我在训练数据中放入了5张独特的面孔(每张面孔和一张标签中的一个),它非常擅长检测。因此,您每人不需要20张以上的图像,但是我想这将极大地帮助您...

   face = new HaarCascade("haarcascade_frontalface_default.xml"); //You will need an XML training file 
   gray = MyImage.Convert<Gray, Byte>();
   MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(face,1.2, 10,
      Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
      new Size(20, 20));

其中MyImage是您的实际文件(作为同一类的图像对象)。您可以在这里阅读有关Haar级联对象检测的信息:https://docs.opencv.org/3.4/d7/d8b/tutorial_py_face_detection.html

所以可以说,您的facesDetected数组中现在只有一个人脸(当MyImage中有多个人脸时,第二维索引找到的人脸总数):

face = MyImage.Copy(facesDetected[0][0].rect).Convert<Gray, byte>().Resize(100, 100, 
Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);

现在,您可以使用已调整大小和转换后的面孔。因此,一旦您捕获了所有训练数据的标准化面部,就将它们保存到图像阵列,将标签保存在字符串阵列中,并使用以下命令来识别面部:

    MCvTermCriteria termCrit = new MCvTermCriteria(TrainingImages.Length, 0.001);
    EigenObjectRecognizer recognizer = new EigenObjectRecognizer(
                       TrainingImages, //as Image<Gray, byte>[] array
                       TrainingImageLabels, //as string[] array
                       3000,
                       ref termCrit);
                    name = recognizer.Recognize(result);
                    // Name will contain the recognised label

这在您进行了预训练的图像时效果很好,就我而言,我正尝试检测出独特的面孔。此方法的工作原理类似于统计信息,我正在尝试弄清楚Recognizer是否能够返回一定百分比的置信度,我可以用它来拒绝建议的名称。但是,希望对您有所帮助!