EmguCv 中使用哪种策略进行 SVM 分类?

Posted

技术标签:

【中文标题】EmguCv 中使用哪种策略进行 SVM 分类?【英文标题】:Which strategy is used in EmguCv for SVM Classification? 【发布时间】:2016-02-18 14:02:17 【问题描述】:

目前我正在做我的学术项目(社交媒体网站)。我的意图是当用户发布一张图片时,系统应该识别出这张脸并用她的名字进行标记。

作为之前的工作,我创建了 5 个用户。 对于训练图像,当用户设置她的个人资料照片时,系统将使用 EmguCv (DetectHaarCascade) 检测它并将图像作为位图保存在文件夹中。该人脸的标签将是用户的用户 ID,标签保存在文件夹内的文本文件中。 作为训练图像,我为每个用户上传并标记了 10 张图像。

下一部分是用户发布照片时。系统应该识别出这张脸并用她的名字标记它。我正在使用 SVM 进行识别和分类。

我的检测码:

    //Face Detection
    MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(
                      haar,
                      1.2,
                      4,
                      HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
                      new Size(20, 20));
    foreach (MCvAvgComp f in facesDetected[0])
    
     result = currentFrame.Copy(f.rect).Convert<Gray, byte>().Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
     // at the beginning i am added all the existing images to an List<Image<Gray, byte>> trainingImages and labels to List<string> labels 
     trainingImages.Add(result );
     labels.Add(Session["UserId"].ToString())
     File.WriteAllText((Server.MapPath("~/TrainedFaces/TrainedLabels.txt")), trainingImages.ToArray().Length.ToString() + "%");

       for (int i = 1; i < trainingImages.ToArray().Length + 1; i++)
       
        //saving the trained images and labells
        trainingImages.ToArray()[i - 1].Save(Server.MapPath("~/TrainedFaces/") + "face" + i + ".bmp");
        File.AppendAllText(Server.MapPath("~/TrainedFaces/TrainedLabels.txt"), labels.ToArray()[i - 1] + "%");
       
   

我的 SVM 训练代码:

/*
1. Loaded all the images to trainingImages
2.Loaded all the labels to labels
*/

// Converting My labesl and images to Matrix for preparing training data and training label    

     Matrix<float> TrainindData = new Matrix<float>(trainingImages.Count, 100 * 100);
        int ii = 0;

        foreach (Image<Gray, float> img in trainingImages)
        
            int jj = 0;
            Matrix<float> Imagemtrx = new Matrix<float>(img.Width, img.Height);
            img.CopyTo(Imagemtrx);
            for (int k = 0; k < Imagemtrx.Rows; k++)
            
                for (int j = 0; j < Imagemtrx.Cols; j++)
                
                    TrainindData.Data[ii, jj] = Imagemtrx[k, j];
                    jj++;
                
            
            ii++;
        
        Matrix<float> TrainedLabels = new Matrix<float>(labels.Count, 1);
        int kk = 0;
        foreach (int lab in labels)
        
            TrainedLabels[kk, 0] = lab;
            kk++;
        

     SVM model = new SVM();

     SVMParams p = new SVMParams();
        p.KernelType = Emgu.CV.ML.MlEnum.SVM_KERNEL_TYPE.LINEAR;
        //p.SVMType = Emgu.CV.ML.MlEnum.SVM_TYPE.ONE_CLASS;
        p.SVMType = Emgu.CV.ML.MlEnum.SVM_TYPE.C_SVC;
        p.C = 1;
        p.TermCrit = new MCvTermCriteria(100, 0.00001);

        bool trained = model.Train(TrainindData, TrainedLabels, null, null, p);

我的识别和分类代码:

MCvAvgComp[][] faces=grayFrame.DetectHaarCascade(haar,1.2,10,HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,new Size(20, 20));
foreach (MCvAvgComp face in faces[0])
        
            InputFrame.Draw(face.rect, new Bgr(Color.Red), 1);
            t = t + 1;
            Image<Gray, float> result = InputFrame.Copy(face.rect).Convert<Gray, float>().Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
            //result._EqualizeHist();
            Matrix<float> TestImageMatix = new Matrix<float>(result.Width, result.Height);
            result.CopyTo(TestImageMatix);
            Matrix<float> TestData = new Matrix<float>(1, result.Width * result.Height);
            int z = 0;
            for (int k = 0; k < TestImageMatix.Rows; k++)
            
                for (int j = 0; j < TestImageMatix.Cols; j++)
                
                    TestData.Data[0, z] = TestImageMatix[k, j];
                    z++;
                
            
            //Here I will Get the UserId as class label. I can find name from database using this Id
            float result1 = model.Predict(TestData);

现在的问题是,当我上传属于任何现有类的图像时,它会正确识别和识别人。但是当我发布一张不同的照片(社交媒体中不存在的人的照片)时,它会被分配给现有的类别标签之一。

我的问题是:

    我只想识别合适的人。剩余的可以标记为未知或其他(我不知道是否需要任何其他方法)

    我读到了“一对一”和“一对一”的策略。我的代码中使用了哪一个?

    如果没有人使用,那么如何实现呢?

    Emgu CV 已经包含 SVM。 It中使用了哪种类型?

【问题讨论】:

【参考方案1】:

我读到了“一对一”和“一对一”的策略。我的代码中使用了哪一个?如果没有人使用,那么如何实现它们? Emgu CV 已经包含 SVM。里面用的是什么类型?

您正在使用 One vs All 策略,该策略在 OpenCV 中使用 n*(n-1)/2 One Vs One 分类器实现(n 是标签的数量)。

我只想识别合适的人。剩余的可以标记为未知或其他(我不知道是否需要任何其他方法)

您可以构建n*(n-1)/2 One Vs One 分类器,然后从predict 获得原始响应(仅适用于 2 类问题)。大多数响应标识输出类。 如果分类类别的最大响应低于阈值,则可以说如果正确识别,则没有类别。

或者您可以使用n 一类分类器,然后再次检查每个分类器的响应是否低于给定阈值。

【讨论】:

通过查看我的代码,您能否建议我从一对一更改为一对一的重写内容,以及如何获得多数响应? @三木 不,对不起,我不会用 C# 编写代码。这些是一般准则。 你能给出构建 n*(n-1)/2 分类器的步骤吗?在哪里指定这个 n*(n-1)/2? @三木 类似:for i = 1 : n for j = i+1 : n train one vs one with labels (i,j) 好的。 !然后如何组合火车以及我应该在哪里编写预测代码@Miki

以上是关于EmguCv 中使用哪种策略进行 SVM 分类?的主要内容,如果未能解决你的问题,请参考以下文章

第八篇:支持向量机 (SVM)

使用 SVM 对文本数据进行多标签分类

调整 SVM OVO 和 OVA 中的超参数以进行多类分类

哪种模型适合预测百分比? [关闭]

在 MapReduce 中组合 SVM 分类器

机器学习之SVM多分类