0

我是 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";
}

我的代码有什么问题?

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

4

1 回答 1

3
  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)。
于 2013-05-20T14:22:43.400 回答