基于opencv的hog+svm简单分类实现

来源:互联网 发布:qq三国单刀赴会第一js 编辑:程序博客网 时间:2024/04/27 17:17

hog特征是一种进行物体检测的特征,常常被用来进行行人检测和物体分类。本文是利用opencv中的hog特征提取算法结合svm分类器进行简单的物体分类。

代码

#include <opencv2/core/core.hpp>#include <opencv2/ml/ml.hpp>#include <opencv2/features2d/features2d.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/nonfree/features2d.hpp>#include <opencv2/legacy/legacy.hpp>#include <opencv2/objdetect/objdetect.hpp>#include <string>#include <stdio.h>#include <iostream>using namespace cv;using namespace std;using namespace cv;using namespace std;int main(){    string classnum[5];    classnum[0] = "./elephant/image_";    classnum[1] = "./butterfly/image_";    classnum[2] = "./cup/image_";    classnum[3] = "./camera/image_";    classnum[4] = "./crocodile_head/image_";    vector<Mat> imageall;    Mat data;    const int trainnum = 45;    const int testnum = 5;    const int desnum = 30;    const int k = 200;    HOGDescriptor hog(Size(128, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);//定义hog描述子    for (int i = 0; i < 5; i++)    for (int j = 1; j <= trainnum; j++)    {        string num;        char numm[10];        sprintf(numm, "%04d.jpg", j);        num = numm;        string name = classnum[i] + num;        cout << name << endl;        Mat image1 = imread(name, 0);        resize(image1, image1, Size(128, 128));        cout <<"image:"<< image1.size() << endl;        imshow("1", image1);        vector<KeyPoint> keypoints1, keypoints2;        //SurfFeatureDetector detector(desnum);        //detector.detect(image1, keypoints1);        //SiftDescriptorExtractor Desc;        vector<float> descriptors;        float fea[8100];        //float fea[3459];        hog.compute(image1, descriptors, Size(4, 4));//提取hog特征        int dim = descriptors.size();        cout << dim << endl;        for (int i = 0; i < dim; i++)            fea[i] = descriptors[i];        data.push_back(Mat(1, dim, CV_32FC1, fea));    }    cout << data.size() << endl;    Mat fealabel;    for (int i = 0; i < trainnum*5; i++)    {        fealabel.push_back(Mat(1, 1, CV_32FC1, i / trainnum));    }    CvSVMParams params;    params.svm_type = CvSVM::C_SVC;    params.kernel_type = CvSVM::LINEAR;    params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 20000, 1e-6);    // 对SVM进行训练    CvSVM SVM;    SVM.train(data, fealabel, Mat(), Mat(), params);    for (int i = 0; i < 5 * trainnum; i++)    {        // cout<<feature.row(i)<<endl;        cout << i / trainnum << " " << SVM.predict(data.row(i)) << endl;    }    Mat test;    //测试过程    for (int i = 0; i < 5; i++)    for (int j =50-testnum+1; j <= 50; j++)    {        string num;        char numm[10];        sprintf(numm, "%04d.jpg", j);        num = numm;        string name = classnum[i] + num;        cout << name << endl;        Mat image1 = imread(name, 0);        resize(image1, image1, Size(128, 128));        cout << "image:" << image1.size() << endl;        imshow("1", image1);        vector<KeyPoint> keypoints1, keypoints2;        SurfFeatureDetector detector(desnum);        detector.detect(image1, keypoints1);        SiftDescriptorExtractor Desc;        vector<float> descriptors;        float fea[8100];        hog.compute(image1, descriptors, Size(4, 4));        int dim = descriptors.size();        cout << dim << endl;        for (int i = 0; i < dim; i++)            fea[i] = descriptors[i];        test.push_back(Mat(1, dim, CV_32FC1, fea));    }    int count = 0;    for (int i = 0; i < 5 * testnum; i++)    {        // cout<<feature.row(i)<<endl;        int a = i / testnum;        int b = SVM.predict(test.row(i));        if (a == b)            count++;        cout << a << " " << b << endl;    }    cout << count*1.0 / (5 * testnum) << endl;    waitKey();}

注意hog特征在使用svm训练时一定要用linear的模型,我理解是用其他的模型容易产生过拟合。opencv svm参数是这样设置的:
params.kernel_type = CvSVM::LINEAR;
还有训练之前注意吧图片都resize成一样大小~

1 0