C# - Emgu Cv - 人脸识别 - 将保存到 Access 数据库的人脸训练集作为二进制文件加载到 EigenObjectRecognizer 中以进行人脸识别

Posted

技术标签:

【中文标题】C# - Emgu Cv - 人脸识别 - 将保存到 Access 数据库的人脸训练集作为二进制文件加载到 EigenObjectRecognizer 中以进行人脸识别【英文标题】:C# - Emgu Cv - Face Recognition- Loading training sets of Faces saved to Access database as a binary in to EigenObjectRecognizer for Face recognition 【发布时间】:2013-05-03 23:02:48 【问题描述】:

我很难将训练集从 Ms Access 数据库加载到执行人脸识别的主窗体中。我将带有名称和 ID 的训练集作为具有 OLE 对象格式的二进制数据保存到数据库中。我用来更改、保存和读取数据库中的数据并保存到训练集中的方法是

private static byte[] ConvertImageToBytes(Image InputImage)
    
        using (Bitmap BmpImage = new Bitmap(InputImage))
        
            using (MemoryStream MyStream = new MemoryStream())
            
                BmpImage.Save(MyStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] ImageAsBytes = MyStream.ToArray();
                return ImageAsBytes;
            
        
    

我用来将转换后的字节数据存储到数据库的方法如下:

   private void StoreData(byte[] ImageAsBytes,String NameStudent,String IDStudent)
    

        if (DBConnection.State.Equals(ConnectionState.Closed))
            DBConnection.Open();
        try
        

            //MessageBox.Show("Saving image at index : " + rowPosition);
            using (OleDbCommand insert = new OleDbCommand(String.Format("Insert INTO
               TrainingSet(rowPosition,StudentName,StudentID,StudentFace) values ('
                0','1','2',@StudentFace)", rowPosition, NameStudent, IDStudent),
                DBConnection))
            
        OleDbParameter imageParameter = insert.Parameters.AddWithValue(@"StudentFace",
                   SqlDbType.Binary);
       imageParameter.Value = ImageAsBytes;
       imageParameter.Size = ImageAsBytes.Length;
       int rowsAffected = insert.ExecuteNonQuery();
       MessageBox.Show(String.Format("Data stored successfully in 0
                                       Row",rowsAffected));
         
            rowPosition++;

        
        catch (Exception ex)
        
            MessageBox.Show(ex.Message);
            MessageBox.Show(ex.Message);
        
        finally
        
            RefreshDBConnection();
        
      

我用来读取这个二进制数据的方法如下:

    private Image ReadImageFromDB()
    

        Image FetchedImg;
        if (rowNumber >= 0)
        

        byte[] FetchedImgBytes = (byte[])LocalDataTable.Rows[rowNumber]["StudentFace"];
            MemoryStream stream = new MemoryStream(FetchedImgBytes);
            FetchedImg = Image.FromStream(stream);
            return FetchedImg;
        
        else
        

            MessageBox.Show("There are no images in the database yet.Please reconnect
                       or add some pictures.");
            return null;
        

    

我已经成功地将训练集/图像作为二进制数据保存到数据库中。问题是当我加载这些训练集进行识别时。

        // Declaring the variables=====trainingImages is where the training sets are
        // loaded from the database NameLabels and IDLabels are text in the database
        // and where name and Id of subject
        //is saved.
      List<Image<Gray,byte>> trainingImages = new List<Image<Gray,byte>>();
      List<string> NameLables= new List<string>();
      List<string> IDLables = new List<string>();
      int ContTrain, NumNameLabels,NumIDLabels, t;

   //The training sets from the database are loaded in to the facerecognizer code as 
   //       follows

  public FaceRecognizer()
    
        InitializeComponent();

        try
        
            //Load previous trained and labels for each image from the database Here
        RefreshDBConnection();
        String[] NameLabels = (String[])LocalDataTable.Rows[rowNumber]["StudentName"];
        NumNameLabels = Convert.ToInt16(NameLabels[0]);
        String[] IDLabels = (String[])LocalDataTable.Rows[rowNumber]["StudentID"];
        NumIDLabels = Convert.ToInt16(IDLabels[0]);

        if (NumNameLabels == NumIDLabels)
         
          ContTrain = NumNameLabels;
          string LoadFaces;
          // Converting the master image to a bitmap
          Image imageFromDB;
          Bitmap imageChangedToBitmap;
          // Normalizing it to grayscale
          Image<Gray, Byte> normalizedMasterImage;

          for (int tf = 1; tf < NumNameLabels + 1; tf++)
           
              imageFromDB = ReadImageFromDB();
              //image loaded from the database is converted in to Bitmap and then 
              //convert the bitmap image in to Image<Gray,byte> for input to 
              //EigenObjectRecognizer(,,,) 
             imageChangedToBitmap = new Bitmap(imageFromDB);
              normalizedMasterImage = new Image<Gray, Byte>(imageChangedToBitmap);
              LoadFaces = String.Format("face0.bmp", tf);
              trainingImages.Add(normalizedMasterImage);
                //trainingImages.Add(new Image<Gray, byte>());
              NameLables.Add(NameLabels[tf]);
              IDLables.Add(IDLabels[tf]);
              rowNumber = rowNumber + 1;
            
         
       else
           MessageBox.Show("There's a conflict between Name labels and id labels");
        
      catch (Exception e)
        
   MessageBox.Show("Nothing in the database, please add at least a
               face.Train the database","Triained faces load",MessageBoxButtons.OK,
               MessageBoxIcon.Exclamation);
        

    

即使在数据库中保存了面孔,我也只会在表单加载时收到消息。我已经使用了 EigenObjectRecognizer,如有必要我会发布代码。

【问题讨论】:

您应该查看另一个最近的问题here。你们两个也许可以互相帮助。 我无法联系到提出类似问题的人,您是否有可能收到他的电子邮件或其他信息。 @Sisay 你能发布 EigenObjectRecognizer 代码吗?我正在尝试做与相同的事情 【参考方案1】:

在加载人脸部分,你没有通过face1、face2、face3等保存,所以无法加载使用;

LoadFaces = String.Format("face0.bmp", tf);

【讨论】:

以上是关于C# - Emgu Cv - 人脸识别 - 将保存到 Access 数据库的人脸训练集作为二进制文件加载到 EigenObjectRecognizer 中以进行人脸识别的主要内容,如果未能解决你的问题,请参考以下文章

C# - Emgu CV - 人脸识别代码在 EigenObjectRecognizer 处停止执行并无错误退出

EMGU CV 2.4.9 人脸识别准确率问题

如何将 Emgu.cv 用于未知人员?

如何在人脸识别 Emgu CV 上检测未知人脸

Emgu CV 人脸识别:在多个文件上并行运行 DetectHaarCascade 问题

将“Emgu.CV.Image<Emgu.CV.Structure.Bgr,byte>”转换为“System.Drawing.Image”