# Why hog + pca to svm can not work

**URL:** <https://forum.opencv.org/t/why-hog-pca-to-svm-can-not-work/8183>\
**Category:** Uncategorized\
**Tags:** objdetect\
**Created:** [March 30, 2022, 10:29am UTC](https://forum.opencv.org/t/why-hog-pca-to-svm-can-not-work/8183 "2022-03-30T10:29:01Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![fatalfeel](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/fatalfeel/32/4865_2.png) [@fatalfeel](https://forum.opencv.org/u/fatalfeel)\
**Post date:** [March 30, 2022, 10:29am UTC](https://forum.opencv.org/t/why-hog-pca-to-svm-can-not-work/8183/1 "2022-03-30T10:29:01Z")

</div>

```auto
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/ml.hpp"
#include "opencv2/objdetect.hpp"
#include "opencv2/videoio.hpp"

using namespace cv;
using namespace cv::ml;
using namespace std;

static void load_images( const String& dirname, Size imgsize, vector<Mat>& img_lst )
{
    vector< String > files;
    glob( dirname, files );

    for ( size_t i = 0; i < files.size(); ++i )
    {
        Mat gray;
        Mat img = imread( files[i] ); // load the image 0=IMREAD_GRAYSCALE
        if ( img.empty() )
        {
            cout << files[i] << " is invalid!" << endl; // invalid image, skip it.
            continue;
        }

        if( img.cols*img.rows != imgsize.width * imgsize.height )
            cv::resize( img, img, imgsize, 0, 0, INTER_LINEAR_EXACT);
        cvtColor(img, gray, COLOR_BGR2GRAY);
        img_lst.push_back( gray );
    }
}

void computeHOGs( Size imgsize, const vector< Mat >& img_lst, vector< Mat >& gradient_lst, bool use_flip )
{
    Mat fimg;
    Mat desc_clone;
    HOGDescriptor hog;
    vector<float> descriptors;
    Size feature_size= Size(16,16);
    Size pad_size = Size(0,0);

    hog.winSize = imgsize;

    for( size_t i = 0 ; i < img_lst.size(); i++ )
    {
        if ( img_lst[i].cols >= imgsize.width && img_lst[i].rows >= imgsize.height )
        {
            //test pca only
            /*Mat desc_clone = img_lst[i].reshape(1,1);
            gradient_lst.push_back( desc_clone );*/

            //hog.compute( gray, descriptors, Size( 8, 8 ), Size( 0, 0 ) );
            hog.compute( img_lst[i], descriptors, feature_size, pad_size );

            //gradient_lst.push_back( Mat( descriptors ).clone() );
            //Mat desc_clone = Mat(descriptors).clone();
            desc_clone = Mat(descriptors).clone().reshape(1,1);
            gradient_lst.push_back( desc_clone );

            if ( use_flip )
            {
                //flip( gray, gray, 1 );
                flip( img_lst[i], fimg, 1 );
                hog.compute( fimg, descriptors, feature_size, pad_size );
                gradient_lst.push_back( Mat( descriptors ).clone() );
            }
        }
    }
}

/*static void pca_load(const string &file_name, cv::PCA _pca)
{
    FileStorage fs(file_name,FileStorage::READ);
    fs["mean"] >> _pca.mean ;
    fs["e_vectors"] >> _pca.eigenvectors ;
    fs["e_values"] >> _pca.eigenvalues ;
    fs.release();
}

static void pca_save(const string &file_name, cv::PCA _pca)
{
    FileStorage fs(file_name,FileStorage::WRITE);
    fs << "mean" << _pca.mean;
    fs << "e_vectors" << _pca.eigenvectors;
    fs << "e_values" << _pca.eigenvalues;
    fs.release();
}*/

int main(int argc, char** argv)
{
    int positive_count;
    int negative_count;
    //vector<Mat> train_images, test_images; //This variable will be loaded with a set of train_images to perform PCA on.
    vector<int> labels;
    vector<Mat> pos_lst, neg_lst, test_lst;
    vector<Mat> train_gradients, test_gradients;
    Size image_size = Size(128, 256);

    load_images("./pos", image_size, pos_lst);
    computeHOGs( image_size, pos_lst, train_gradients, false );
    positive_count = train_gradients.size();
    labels.assign( positive_count, +1 );

    load_images("./neg", image_size, neg_lst);
    computeHOGs( image_size, neg_lst, train_gradients, false );
    negative_count = train_gradients.size() - positive_count;
    labels.insert(labels.end(), negative_count, -1);

    /*char testv[16] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    Mat a1(2,8,CV_8UC1);
    Mat a2(2,8,CV_8UC1);
    Mat a3(1,8,CV_8UC1,testv);
    cout << a3 << endl << endl;
    a1.row(0) = a3;
    a3.copyTo(a2.row(0)); //equal=> a2.row(0) = a3 + 0;
    cout << a1 << endl;
    cout << a2 << endl;*/

    //Load the train_images into a Matrix
    Mat desc_mat(train_gradients.size(), train_gradients[0].rows * train_gradients[0].cols, CV_8UC1);
    for (uint32_t i=0; i<train_gradients.size(); i++)
    {
        //desc_mat.row(i) = train_images[i].reshape(1, 1) + 0;
        //Mat testm = train_gradients[i];
        //train_gradients[i].reshape(1, 1).copyTo(desc_mat.row(i)); //reshaped in computeHOGs
        train_gradients[i].copyTo(desc_mat.row(i));
    }

    printf("pca start trained\n");
    //int nEigens = train_images.size() - 1; //Number of Eigen Vectors.
    int nEigens = train_gradients.size();
    Mat average = Mat();
    PCA pca_trainer(desc_mat, average, CV_PCA_DATA_AS_ROW, nEigens);
    Mat data(desc_mat.rows, nEigens, CV_32FC1); //This Mat will contain all the Eigenfaces that will be used later with SVM for detection
    //Project the train_images onto the PCA subspace
    for(uint32_t i=0; i<train_gradients.size(); i++)
    {
        Mat projectedMat(1, nEigens, CV_32FC1);
        pca_trainer.project(desc_mat.row(i), projectedMat);
        //data.row(i) = projectedMat.row(0) + 0;
        //projectedMat.row(0).copyTo(data.row(i));
        projectedMat.copyTo(data.row(i));
    }
    printf("pca end trained\n");
    //pca_save("pca_data.xml",pca_trainer);

    //param = SVMParams( SVM::C_SVC, SVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
    Ptr<SVM> svm = SVM::create();
    svm->setC( 1.0 );
    svm->setKernel( SVM::RBF );

    printf("svm start trained\n");
    svm->train( data, ROW_SAMPLE, labels );
    printf("svm end trained\n");
    //svm->save("svm_data.xml");
    //svm->load("svm_data.xml");

    int ret;
    //Mat dst;
    load_images("./test", image_size, test_lst);
    computeHOGs( image_size, test_lst, test_gradients, false );
    for(auto& dst : test_gradients)
    {
        //Mat dst = src.reshape(1, 1);
        //src.copyTo(dst);
        Mat predictMat(1, nEigens, CV_32FC1);
        pca_trainer.project(dst, predictMat);
        ret = svm->predict(predictMat);
        cout<<ret<<endl;
    }

	return EXIT_SUCCESS;
}

//-----------------------------------------------------------------------------------------
pca only
for( size_t i = 0 ; i < img_lst.size(); i++ )
    {
        if ( img_lst[i].cols >= imgsize.width && img_lst[i].rows >= imgsize.height )
        {
            //test pca only
            Mat desc_clone = img_lst[i].reshape(1,1);
            gradient_lst.push_back( desc_clone );

            /*//hog.compute( gray, descriptors, Size( 8, 8 ), Size( 0, 0 ) );
            hog.compute( img_lst[i], descriptors, feature_size, pad_size );

            //gradient_lst.push_back( Mat( descriptors ).clone() );
            //Mat desc_clone = Mat(descriptors).clone();
            desc_clone = Mat(descriptors).clone().reshape(1,1);
            gradient_lst.push_back( desc_clone );

            if ( use_flip )
            {
                //flip( gray, gray, 1 );
                flip( img_lst[i], fimg, 1 );
                hog.compute( fimg, descriptors, feature_size, pad_size );
                gradient_lst.push_back( Mat( descriptors ).clone() );
            }*/
        }
    }

// ----------------------------------------------------------------------------------------

```

full source

> **[opencv\_hog\_pca\_svm\_train.tar](https://www.mediafire.com/file/53de0z8s9zyy66j/opencv_hog_pca_svm_train.tar.gz)**
>
> MediaFire is a simple to use free service that lets you put all your photos, documents, music, and video in a single place so you can access them anywhere and share them everywhere.

in python predict correct

> **[GitHub - fatalfeel/hog\_pca\_svm\_detection: hog pca svm car detection](https://github.com/fatalfeel/hog_pca_svm_detection)**
>
> hog pca svm car detection. Contribute to fatalfeel/hog\_pca\_svm\_detection development by creating an account on GitHub.

in opencv  
pca + svm predict correct  
but hog + pca + svm predict fail

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [March 30, 2022, 12:52pm UTC](https://forum.opencv.org/t/why-hog-pca-to-svm-can-not-work/8183/2 "2022-03-30T12:52:05Z")

</div>

please, “is ok”, “cannot work” or “is failed” are useless to describe your problem.

try again, tell us what happens (or fails to do so), if there are errors, show us !

(also, why is this labelled `object-detection` ? you’re doing _classification_)

---

<div class="post-metadata">

**Author:** ![fatalfeel](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/fatalfeel/32/4865_2.png) [@fatalfeel](https://forum.opencv.org/u/fatalfeel)\
**Post date:** [April 1, 2022, 7:57am UTC](https://forum.opencv.org/t/why-hog-pca-to-svm-can-not-work/8183/3 "2022-04-01T07:57:19Z")

</div>

Done finally

> **[GitHub - fatalfeel/hog\_pca\_svm\_slider\_nms\_cpp: hog pca svm slider nms cpp](https://github.com/fatalfeel/hog_pca_svm_slider_nms_cpp)**
>
> hog pca svm slider nms cpp. Contribute to fatalfeel/hog\_pca\_svm\_slider\_nms\_cpp development by creating an account on GitHub.
