cv :: SVM为每个样本响应一个类

时间:2013-05-20 06:43:19

标签: opencv machine-learning svm

我是Match faces的新手,我正在尝试学习如何将SVM与HOG描述符一起使用。 我用SVM编写了一个简单的人脸识别器,但是当我激活它时,代码总是返回1

float *getHOG(const cv::Mat &image, int* count)//Compute HOG
{
    cv::HOGDescriptor hog;
    std::vector<float> res;
    cv::Mat img2;
    cv::resize(image, img2, cv::Size(64, 128));
    hog.compute(img2, res, cv::Size(8, 8), cv::Size(0, 0));
    *count = res.size();
    float* result = new float[*count];
    for(int i = 0; i < res.size(); i++)
    {
        result[i] = res[i];
    }
    return result;
}

const int dataSetLength = 10;
float **getTraininigData(int* setlen, int* veclen)//Load some samples of data
{
    char *names[dataSetLength] = {
        "../faces/s1/1.pgm",
        "../faces/s1/2.pgm",
        "../faces/s1/3.pgm",
        "../faces/s1/4.pgm",
        "../faces/s1/5.pgm",
        "../faces/cars/1.jpg",
        "../faces/cars/2.jpg",
        "../faces/cars/3.jpg",
        "../faces/cars/4.jpg",
        "../faces/cars/5.jpg",
    };

    float **res = new float* [dataSetLength];
    for(int i = 0; i < dataSetLength; i++)
    {
        std::cout<<names[i]<<"\n";
        cv::Mat img = cv::imread(names[i], 0);
        res[i] = getHOG(img, veclen);
    }
    *setlen = dataSetLength;
    return res;
}

void test()//Training and activate SVM
{
    int setlen, veclen;
    float **trainingData = getTraininigData(&setlen, &veclen);
    float *labels = new float[dataSetLength];
    for(int i = 0; i < dataSetLength; i++)
    {
        labels[i] = (i < dataSetLength/2)? 0.0 : 1.0;
    }
    cv::Mat labelsMat(setlen, 1, CV_32FC1, labels);
    cv::Mat trainingDataMat(setlen, veclen, CV_32FC1, trainingData);

    cv::SVMParams params;
    params.svm_type    = cv::SVM::C_SVC;
    params.kernel_type = cv::SVM::LINEAR;
    params.term_crit   = cv::TermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
    std::cout<<labelsMat<<"\n";

    cv::SVM SVM;
    SVM.train(trainingDataMat, labelsMat, cv::Mat(), cv::Mat(), params);
    cv::Mat img = cv::imread("../faces/s1/2.pgm", 0);//sample from train data, but ansewer is 1 for every sample
    auto desc = getHOG(img, &veclen);
    cv::Mat sampleMat(1, veclen, CV_32FC1, desc);
    float response = SVM.predict(sampleMat);
    std::cout<<"resp "<< response<<"\n";
}

我的代码出了什么问题?

对不起我的写作错误。英语不是我的母语

1 个答案:

答案 0 :(得分:3)

  1. 您没有太多的训练数据。请注意Dalal和Triggs在他们关于HOG(http://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf)的原始论文中如何使用数千个示例来训练SVM,你只有5个负面和5个正面。
  2. 您尚未设置C参数(您需要通过交叉验证找到一个好的值) - 您将需要更多数据。
  3. 面部和汽车的HOG描述符可能无法与线性内核分离,请尝试RBF。 但这不太可能是一个问题,因为D&amp; L在他们的论文中使用线性SVM。
  4. 阅读本文:http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf
  5. 如果您还没有这样做,请让SVM为更简单的情况工作(例如,只使用图像补丁而不是HOG)。