title: Face Recognition Using EMGU CV 3.1.0
body: <p>The function <code>DetectAndRecognizeFaces</code> is to detect a face and pass the detected image to the <code>Recognize</code> method which returns a name of recognized face based on the label.</p>
  
  <p><code>LoadTrainingSet</code> function is to fetch data from SQL database and <code>LoadTrainingData</code> method is to train the <code>eigenfacerecognizer</code>.</p>
  
  <p>The problem is that the predict function never returns <code>-1</code> for Unknown facees and always returns <code>match</code> if the detected face is not present in the database.</p>
  
  <p>The Code:</p>
  
  <pre><code>private void DetectAndRecognizeFaces()
  {
      Image&lt;Gray, byte&gt; grayframe = ImageFrame.Convert&lt;Gray, byte&gt;();
  
      //Assign user-defined Values to parameter variables:
      minNeighbors = int.Parse(comboBoxMinNeigh.Text);  // the 3rd parameter
      windowsSize = int.Parse(textBoxWinSize.Text);   // the 5th parameter
      scaleIncreaseRate = Double.Parse(comboBoxScIncRte.Text); //the 2nd parameter
  
      //detect faces from the gray-scale image and store into an array of type 'var',i.e 'MCvAvgComp[]'
      var faces = haar.DetectMultiScale(grayframe, scaleIncreaseRate, minNeighbors, Size.Empty); //the actual face detection happens here
  
      MessageBox.Show("Total Faces Detected: " + faces.Length.ToString());
  
      Bitmap BmpInput = grayframe.ToBitmap();
      Bitmap ExtractedFace;   //empty
      Graphics grp;
      //MCvFont font = new MCvFont(FONT.CV_FONT_HERSHEY_TRIPLEX, 0.5d, 0.5d);
  
      faceRecognizer.Load(recognizeFilePath);
      foreach (var face in faces)
      {
          t = t + 1;
          result = ImageFrame.Copy(face).Convert&lt;Gray, byte&gt;().Resize(100, 100, Inter.Cubic);
  
          //set the size of the empty box(ExtractedFace) which will later contain the detected face
          ExtractedFace = new Bitmap(face.Width, face.Height);
  
          //assign the empty box to graphics for painting
          grp = Graphics.FromImage(ExtractedFace);
          //graphics fills the empty box with exact pixels of the face to be extracted from input image
          grp.DrawImage(BmpInput, 0, 0, face, GraphicsUnit.Pixel);
  
  
  
          string name = Recognise(result);
          if (name == "Unknown")
          {
              ImageFrame.Draw(face, new Bgr(Color.Red), 3);
  
              MessageBox.Show("Face Name is: " + name.ToString());
              ImageFrame.Draw(name, new Point(face.X - 2, face.Y - 2), FontFace.HersheyComplex, 0.5,
                  new Bgr(0, 0, 255), 1, LineType.EightConnected, bottomLeftOrigin);
          }
          else
          {
              ImageFrame.Draw(face, new Bgr(Color.Green), 3);
  
              MessageBox.Show("Face Name is: " + name.ToString());
              ImageFrame.Draw(name, new Point(face.X - 2, face.Y - 2), FontFace.HersheyComplex, 0.5,
                  new Bgr(0, 255, 0), 1, LineType.EightConnected, bottomLeftOrigin);
          }
  
  
      CamImageBox.Image = ImageFrame;
  
  }
  
  public string Recognise(Image&lt;Gray, byte&gt; Input_image, int Eigen_Thresh = -1)
  {
      if (_IsTrained)
      {
          faceRecognizer.Load(recognizeFilePath);
          FaceRecognizer.PredictionResult ER = faceRecognizer.Predict(Input_image);
  
          if (ER.Label == -1)
          {
              Eigen_Label = "Unknown";
              Eigen_Distance = 0;
              return Eigen_Label;
          }
          else
          {
              Eigen_Label = Names_List[ER.Label];
              Eigen_Distance = (float)ER.Distance;
              if (Eigen_Thresh &gt; -1) Eigen_threshold = Eigen_Thresh;
  
              //Only use the post threshold rule if we are using an Eigen Recognizer 
              //since Fisher and LBHP threshold set during the constructor will work correctly 
              switch (Recognizer_Type)
              {
                  case ("EMGU.CV.EigenFaceRecognizer"):
                      if (Eigen_Distance &gt; Eigen_threshold) return Eigen_Label;
                      else return "Unknown";
                  case ("EMGU.CV.LBPHFaceRecognizer"):
                  case ("EMGU.CV.FisherFaceRecognizer"):
                  default:
                      return Eigen_Label; //the threshold set in training controls unknowns
              }
          }
  
      }
      else return "";
  }
  
  private void LoadTrainingSet()
  {
      Bitmap bmpImage;
  
      for (int i = 0; i &lt; totalRows; i++)
      {
          byte[] fetchedBytes = (byte[])dataTable.Rows[i]["FaceImage"];
          MemoryStream stream = new MemoryStream(fetchedBytes);
          //stream.Write(fetchedBytes, 0, fetchedBytes.Length);
          bmpImage = new Bitmap(stream);
          trainingImages.Add(new Emgu.CV.Image&lt;Gray, Byte&gt;(bmpImage).Resize(100, 100, Inter.Cubic));
  
          //string faceName = (string)dataTable.Rows[i]["FaceName"];
          int faceName = (int)dataTable.Rows[i]["FaceID"];
          NameLabels.Add(faceName);
          NameLable = (string)dataTable.Rows[i]["FaceName"];
          Names_List.Add(NameLable);
          //ContTrain = NameLabels[i];
      }
      LoadTrainedData();
  }
  
  public void LoadTrainedData()
  {
      if (trainingImages.ToArray().Length != 0)
      {
          var faceImages = new Image&lt;Gray, byte&gt;[trainingImages.Count()];
          var facesIDs = new int[NameLabels.Count()];
          //var facesNames = new string[Names_List.Count()];
          //int[] faceLabels = new int[NameLabels.Count()];
          //MCvTermCriteria termCrit = new MCvTermCriteria(ContTrain, 0.001);
          for (int i = 0; i &lt; trainingImages.ToArray().Length; i++)
          {
              faceImages[i] = trainingImages[i];
              facesIDs[i] = NameLabels[i];
  
          }
  
          try
          {
              faceRecognizer.Train(faceImages, facesIDs);
              faceRecognizer.Save(recognizeFilePath);
              _IsTrained = true;
          }
          catch (Exception error)
          {
              MessageBox.Show(error.ToString());
          }
      }
  
  }
  </code></pre>