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

我在匹配人脸方面是新手,正在尝试学习如何使用带有HOG描述子的SVM。我编写了一个简单的基于SVM的人脸识别器,但在激活它时,代码总是返回1

float *getHOG(const cv::Mat &image, int* count)//计算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)//加载一些数据样本
{
    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()//训练和激活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);//来自训练数据的样本,但每个样本的答案都是1
    auto desc = getHOG(img, &veclen);
    cv::Mat sampleMat(1, veclen, CV_32FC1, desc);
    float response = SVM.predict(sampleMat);
    std::cout<<"resp "<< response<<"\n";
}

我的代码有什么问题?

PS 抱歉我的写作中有错误。英语不是我的母语


回答:

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

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注