SVM + HOG learning and detection methods using HogDescriptor

Dear Erol çıtak

This posting is for cleanning up the SVM + HOG learning and detection methods to help you.


Step 1. Prepare Data.

Prepare Positive and Negative images
Same size and gray scale

And make xml file for a more convenient data management.
Refer to this page for this step



Step 2. Training by SVM

Load positive.xml and Negative.xml and train by SVM
Refer to this page for this step 2




Step 3. Test by SVM

After training, test other images.
Refer to this page for this step 3



Step 4. for using MultiScaleDetection() 

For using Hog.MultiScaleDetection() and other functions.
We have to change the value that result of svm training. 

Refer to this page for Step 4. (There is a method for converting the end of source code)
http://study.marearts.com/2014/11/opencv-svm-learning-method-and-xml.html

after training.
refer to this source code for using method
..
//Load trained SVM xml data
FileStorage svmDX_Xml("XXXXX.xml", FileStorage::READ);
Mat xMat;
svmDX_Xml["SecondSVMd"] >> xMat;
vector< float> VX;  
//copy mat to vector  
VX.assign((float*)xMat.datastart, (float*)xMat.dataend);

//HogDescriptor
HOGDescriptor d( Size(64,64), Size(16,16), Size(8,8), Size(8,8), 9); //must be same with training setting.
d.setSVMDetector(VX);
...
d.detect(...) or d.detectMultiScale(...)

..



Thank you.

Opencv Hog+SVM example of pedestrian detection


source code


#include < iostream>    
#include "opencv2\objdetect\objdetect.hpp"
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\cudaobjdetect.hpp"
#include "opencv2\cudaimgproc.hpp"
#include "opencv2\cudawarping.hpp"


#ifdef _DEBUG               
#pragma comment(lib, "opencv_core300d.lib")       
#pragma comment(lib, "opencv_highgui300d.lib")    
#pragma comment(lib, "opencv_imgcodecs300d.lib")  
#pragma comment(lib, "opencv_objdetect300d.lib")  
#pragma comment(lib, "opencv_imgproc300d.lib")  
#pragma comment(lib, "opencv_videoio300d.lib")    
#pragma comment(lib, "opencv_cudaobjdetect300d.lib")  
#pragma comment(lib, "opencv_cudawarping300d.lib")
#pragma comment(lib, "opencv_cudaimgproc300d.lib")

#else       
#pragma comment(lib, "opencv_core300.lib")       
#pragma comment(lib, "opencv_highgui300.lib")    
#pragma comment(lib, "opencv_imgcodecs300.lib")    
#pragma comment(lib, "opencv_objdetect300.lib")  
#pragma comment(lib, "opencv_imgproc300.lib")  
#pragma comment(lib, "opencv_videoio300.lib")    
#pragma comment(lib, "opencv_cudaobjdetect300.lib")
#pragma comment(lib, "opencv_cudawarping300.lib")
#pragma comment(lib, "opencv_cudaimgproc300.lib")
#endif        

using namespace std;
using namespace cv;


void main()
{


 cv::Ptr< cv::cuda::HOG> d_hog = cv::cuda::HOG::create(Size(48, 96)); //Size(64, 128));// 
 d_hog->setSVMDetector(d_hog->getDefaultPeopleDetector());
 

 //video loading
 Mat img; 
 VideoCapture cap("M:\\____videoSample____\\tracking\\TownCentreXVID.avi");

 //loading test
 cap >> img;
 if (img.empty())
  return;

 //window
 namedWindow("pedestrian", 0);

 //processing time check
 unsigned long AAtime = 0, BBtime = 0;
 
 //resize
 double scale = float(800) / img.cols;
 cuda::GpuMat GpuImg, rGpuImg;
 GpuImg.upload(img);
 cuda::resize(GpuImg, rGpuImg, Size(GpuImg.cols * scale, GpuImg.rows * scale));
 Mat rInimg;
 rGpuImg.download(rInimg);

 while (1)
 {
  //time check
  AAtime = getTickCount();

  //loading
  cap >> img;
  if (img.empty())
   break;

  //resize
  GpuImg.upload(img);
  cuda::resize(GpuImg, rGpuImg, Size(GpuImg.cols * scale, GpuImg.rows * scale));
  rGpuImg.download(rInimg);
  cuda::cvtColor(rGpuImg, rGpuImg, CV_BGR2GRAY);
  
  
  vector< Point> found_locations;
  d_hog->detect(rGpuImg, found_locations);

  std::vector< cv::Rect> found_locations_rect;
  d_hog->detectMultiScale(rGpuImg, found_locations_rect);


  for (int i = 0; i < found_locations_rect.size(); ++i)
  {

   cv::rectangle(rInimg, found_locations_rect[i], CvScalar(0, 0, 255), 1);   
  }


  imshow("pedestrian", rInimg);
  waitKey(10);

  //time check
  BBtime = getTickCount();
  double s_time = (BBtime - AAtime) / getTickFrequency();
  double fps_time = 1/s_time;
  printf("%.2lf sec / %.2lf fps \n", s_time, fps_time); 

 }


}

Extracting two hog feature and comparing by vectors of descriptor in opencv (example source code)


I am wondering that two hog features can compare or not.

There was a article about this question on this page ->
http://stackoverflow.com/questions/11626140/extracting-hog-features-using-opencv

This article introduces that to compare the descriptor values of HOG.
I don't know this comparison is surely exact or not.

I think this comparison need more experiment.




similarity test in video





#include < opencv2\opencv.hpp>  
#include < stdio.h>  


#ifdef _DEBUG          
#pragma comment(lib, "opencv_core249d.lib")  
#pragma comment(lib, "opencv_imgproc249d.lib")   //MAT processing  
#pragma comment(lib, "opencv_highgui249d.lib")  
#pragma comment(lib, "opencv_objdetect249d.lib")  
#else  
#pragma comment(lib, "opencv_core249.lib")  
#pragma comment(lib, "opencv_imgproc249.lib")  
#pragma comment(lib, "opencv_highgui249.lib")  
#pragma comment(lib, "opencv_objdetect249.lib")  
#endif     

#define M_PI 3.1415

using namespace std;  
using namespace cv;  


Mat get_hogdescriptor_visual_image(Mat& origImg,
                                   vector< float>& descriptorValues,
                                   Size winSize,
                                   Size cellSize,                                   
                                   int scaleFactor,
                                   double viz_factor);

int main()  
{  

 //image load
 Mat img1 = imread("./b1.jpg");
 Mat img2 = imread("./c5.jpg");

 //rgb 2 gray
 Mat img1_gray; 
 cvtColor(img1, img1_gray, CV_RGB2GRAY);

 Mat img2_gray; 
 cvtColor(img2, img2_gray, CV_RGB2GRAY);

 //resize smaller
 Mat r_img1_gray;
 resize(img1_gray, r_img1_gray, Size(64, 8));
 Mat r_img2_gray;
 resize(img2_gray, r_img2_gray, Size(64, 8));


 //extractino hog feature
 HOGDescriptor d1( Size(64,8), Size(8,8), Size(4,4), Size(4,4), 9);
 HOGDescriptor d2( Size(64,8), Size(8,8), Size(4,4), Size(4,4), 9);
 // Size(32,16), //winSize
 // Size(8,8), //blocksize
 // Size(4,4), //blockStride,
 // Size(4,4), //cellSize,
 // 9, //nbins,

 //hog feature compute
 vector< float> descriptorsValues1;
 vector< Point> locations1;
 d1.compute( r_img1_gray, descriptorsValues1, Size(0,0), Size(0,0), locations1);
 vector< float> descriptorsValues2;
 vector< Point> locations2;
 d2.compute( r_img2_gray, descriptorsValues2, Size(0,0), Size(0,0), locations2);

 //hog feature size
 //cout << descriptorsValues1.size() << endl;


 ///////////////////////
 //copy vector to mat  
 //create Mat  
 Mat A(descriptorsValues1.size(),1,CV_32FC1); 
 //copy vector to mat  
 memcpy(A.data,descriptorsValues1.data(),descriptorsValues1.size()*sizeof(float));
 //create Mat  
 Mat B(descriptorsValues2.size(),1,CV_32FC1); 
 //copy vector to mat  
 memcpy(B.data,descriptorsValues2.data(),descriptorsValues2.size()*sizeof(float));


 /////////////////////////
 //sum( sqrt( (A.-B)^2 ) )
 Mat C = A-B;
 C = C.mul(C);
 cv::sqrt(C, C);
 cv::Scalar rr = cv::sum(C);
 float rrr = rr(0);
 cout << "Distance: " << rrr << endl;

 
 //hog visualization
 Mat r1 = get_hogdescriptor_visual_image(r_img1_gray, descriptorsValues1, Size(64,8), Size(4,4), 10, 3);
 Mat r2 = get_hogdescriptor_visual_image(r_img2_gray, descriptorsValues2, Size(64,8), Size(4,4), 10, 3);

 imshow("hog visualization1", r1);
 imshow("hog visualization2", r2);

 waitKey(0);

 return 0;
}






refer to this page http://feelmare.blogspot.kr/2015/02/opencv-hog-descriptor-computation-and.html about the function "get_hogdescriptor_visual_image" in example source code.


OpenCV, HOG descriptor computation and visualization (HOGDescriptor function)

This article is about hog feature extraction and visualization.

Hog feature can computer easy using HOGDescriptor method in opencv.

Visualization is little bit complex. But Jürgen Brauer introduce HOG feature visualization function in his blog.
refer to this page -> http://www.juergenwiki.de/work/wiki/doku.php?id=public:hog_descriptor_computation_and_visualization
I thought he is very excellent researcher in computer vision.

So, I introduce hog feature extraction and visualization using his code.


#include < opencv2\opencv.hpp>  
#include < stdio.h>  


#ifdef _DEBUG          
#pragma comment(lib, "opencv_core249d.lib")  
#pragma comment(lib, "opencv_imgproc249d.lib")   //MAT processing  
#pragma comment(lib, "opencv_highgui249d.lib")  
#pragma comment(lib, "opencv_objdetect249d.lib")  
#else  
#pragma comment(lib, "opencv_core249.lib")  
#pragma comment(lib, "opencv_imgproc249.lib")  
#pragma comment(lib, "opencv_highgui249.lib")  
#pragma comment(lib, "opencv_objdetect249.lib")  
#endif     

#define M_PI 3.1415

using namespace std;  
using namespace cv;  


Mat get_hogdescriptor_visual_image(Mat& origImg,
                                   vector< float>& descriptorValues,
                                   Size winSize,
                                   Size cellSize,                                   
                                   int scaleFactor,
                                   double viz_factor);

int main()  
{  

 

 Mat img1 = imread("./1.jpg");

 Mat img1_gray; 
 cvtColor(img1, img1_gray, CV_RGB2GRAY);
 
 Mat r_img1_gray;
 resize(img1_gray, r_img1_gray, Size(32, 16));


 //extractino hog feature
 HOGDescriptor d1( Size(32,16), Size(8,8), Size(4,4), Size(4,4), 9);
 // Size(32,16), //winSize
 // Size(8,8), //blocksize
 // Size(4,4), //blockStride,
 // Size(4,4), //cellSize,
 // 9, //nbins,


 //feature compare
 vector< float> descriptorsValues1;
 vector< Point> locations1;
 d1.compute( r_img1_gray, descriptorsValues1, Size(0,0), Size(0,0), locations1);


 //hog visualization
 Mat r1 = get_hogdescriptor_visual_image(r_img1_gray,
                                   descriptorsValues1,
                                   Size(32,16),
                                   Size(4,4),                                   
                                   10,
                                   5);

 imshow("hog visualization", r1);
 waitKey(0);

 return 0;
}



Mat get_hogdescriptor_visual_image(Mat& origImg,
                                   vector< float>& descriptorValues,
                                   Size winSize,
                                   Size cellSize,                                   
                                   int scaleFactor,
                                   double viz_factor)
{   
    Mat visual_image;
    resize(origImg, visual_image, Size(origImg.cols*scaleFactor, origImg.rows*scaleFactor));
 cvtColor(visual_image, visual_image, CV_GRAY2BGR);

 
    int gradientBinSize = 9;
    // dividing 180° into 9 bins, how large (in rad) is one bin?
    float radRangeForOneBin = 3.14/(float)gradientBinSize; 
 
    // prepare data structure: 9 orientation / gradient strenghts for each cell
 int cells_in_x_dir = winSize.width / cellSize.width;
    int cells_in_y_dir = winSize.height / cellSize.height;
    int totalnrofcells = cells_in_x_dir * cells_in_y_dir;
    float*** gradientStrengths = new float**[cells_in_y_dir];
    int** cellUpdateCounter   = new int*[cells_in_y_dir];
    for (int y=0; y< cells_in_y_dir; y++)
    {
        gradientStrengths[y] = new float*[cells_in_x_dir];
        cellUpdateCounter[y] = new int[cells_in_x_dir];
        for (int x=0; x< cells_in_x_dir; x++)
        {
            gradientStrengths[y][x] = new float[gradientBinSize];
            cellUpdateCounter[y][x] = 0;
 
            for (int bin=0; bin< gradientBinSize; bin++)
                gradientStrengths[y][x][bin] = 0.0;
        }
    }
 
    // nr of blocks = nr of cells - 1
    // since there is a new block on each cell (overlapping blocks!) but the last one
    int blocks_in_x_dir = cells_in_x_dir - 1;
    int blocks_in_y_dir = cells_in_y_dir - 1;
 
    // compute gradient strengths per cell
    int descriptorDataIdx = 0;
    int cellx = 0;
    int celly = 0;
 
    for (int blockx=0; blockx< blocks_in_x_dir; blockx++)
    {
        for (int blocky=0; blocky< blocks_in_y_dir; blocky++)            
        {
            // 4 cells per block ...
            for (int cellNr=0; cellNr< 4; cellNr++)
            {
                // compute corresponding cell nr
                int cellx = blockx;
                int celly = blocky;
                if (cellNr==1) celly++;
                if (cellNr==2) cellx++;
                if (cellNr==3)
                {
                    cellx++;
                    celly++;
                }
 
                for (int bin=0; bin< gradientBinSize; bin++)
                {
                    float gradientStrength = descriptorValues[ descriptorDataIdx ];
                    descriptorDataIdx++;
 
                    gradientStrengths[celly][cellx][bin] += gradientStrength;
 
                } // for (all bins)
 
 
                // note: overlapping blocks lead to multiple updates of this sum!
                // we therefore keep track how often a cell was updated,
                // to compute average gradient strengths
                cellUpdateCounter[celly][cellx]++;
 
            } // for (all cells)
 
 
        } // for (all block x pos)
    } // for (all block y pos)
 
 
    // compute average gradient strengths
    for (int celly=0; celly< cells_in_y_dir; celly++)
    {
        for (int cellx=0; cellx< cells_in_x_dir; cellx++)
        {
 
            float NrUpdatesForThisCell = (float)cellUpdateCounter[celly][cellx];
 
            // compute average gradient strenghts for each gradient bin direction
            for (int bin=0; bin< gradientBinSize; bin++)
            {
                gradientStrengths[celly][cellx][bin] /= NrUpdatesForThisCell;
            }
        }
    }
 
 
    cout << "descriptorDataIdx = " << descriptorDataIdx << endl;
 
    // draw cells
    for (int celly=0; celly< cells_in_y_dir; celly++)
    {
        for (int cellx=0; cellx< cells_in_x_dir; cellx++)
        {
            int drawX = cellx * cellSize.width;
            int drawY = celly * cellSize.height;
 
            int mx = drawX + cellSize.width/2;
            int my = drawY + cellSize.height/2;
 
            rectangle(visual_image,
                      Point(drawX*scaleFactor,drawY*scaleFactor),
                      Point((drawX+cellSize.width)*scaleFactor,
                      (drawY+cellSize.height)*scaleFactor),
                      CV_RGB(100,100,100),
                      1);
 
            // draw in each cell all 9 gradient strengths
            for (int bin=0; bin< gradientBinSize; bin++)
            {
                float currentGradStrength = gradientStrengths[celly][cellx][bin];
 
                // no line to draw?
                if (currentGradStrength==0)
                    continue;
 
                float currRad = bin * radRangeForOneBin + radRangeForOneBin/2;
 
                float dirVecX = cos( currRad );
                float dirVecY = sin( currRad );
                float maxVecLen = cellSize.width/2;
                float scale = viz_factor; // just a visual_imagealization scale,
                                          // to see the lines better
 
                // compute line coordinates
                float x1 = mx - dirVecX * currentGradStrength * maxVecLen * scale;
                float y1 = my - dirVecY * currentGradStrength * maxVecLen * scale;
                float x2 = mx + dirVecX * currentGradStrength * maxVecLen * scale;
                float y2 = my + dirVecY * currentGradStrength * maxVecLen * scale;
 
                // draw gradient visual_imagealization
                line(visual_image,
                     Point(x1*scaleFactor,y1*scaleFactor),
                     Point(x2*scaleFactor,y2*scaleFactor),
                     CV_RGB(0,0,255),
                     1);
 
            } // for (all bins)
 
        } // for (cellx)
    } // for (celly)
 
 
    // don't forget to free memory allocated by helper data structures!
    for (int y=0; y< cells_in_y_dir; y++)
    {
      for (int x=0; x< cells_in_x_dir; x++)
      {
           delete[] gradientStrengths[y][x];            
      }
      delete[] gradientStrengths[y];
      delete[] cellUpdateCounter[y];
    }
    delete[] gradientStrengths;
    delete[] cellUpdateCounter;
 
    return visual_image;
 
}

OpenCV SVM learning method and xml convert method to use in Hog.SetSVMDetector() function

This is example of SVM learning method.
This example is I already have explained in past time.
See the this page - >http://feelmare.blogspot.kr/search/label/SVM

But other contents is added in this example.
That is converting of trained xml file to use in Hog.MultiScaleDetection function.

Converting process is started after svm learning.
See the comment of "the second save option" in source code.

Thank you.



---
#include < stdio.h>
#include < opencv2\opencv.hpp>
//#include < opencv2\gpu\gpu.hpp>

using namespace cv;
using namespace std;


#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")         
#pragma comment(lib, "opencv_imgproc247d.lib")   //MAT processing        
#pragma comment(lib, "opencv_objdetect247d.lib") //HOGDescriptor
//#pragma comment(lib, "opencv_gpu247d.lib")        
//#pragma comment(lib, "opencv_features2d247d.lib")        
#pragma comment(lib, "opencv_highgui247d.lib")        
#pragma comment(lib, "opencv_ml247d.lib")      
//#pragma comment(lib, "opencv_stitching247d.lib");      
//#pragma comment(lib, "opencv_nonfree247d.lib");      
  
#else        
#pragma comment(lib, "opencv_core247.lib")        
#pragma comment(lib, "opencv_imgproc247.lib")        
#pragma comment(lib, "opencv_objdetect247.lib")        
//#pragma comment(lib, "opencv_gpu247.lib")        
//#pragma comment(lib, "opencv_features2d247.lib")        
#pragma comment(lib, "opencv_highgui247.lib")        
#pragma comment(lib, "opencv_ml247.lib")        
//#pragma comment(lib, "opencv_stitching247.lib");      
//#pragma comment(lib, "opencv_nonfree247.lib");      
#endif 

class MySvm: public CvSVM  
{  
public:  
 int get_alpha_count(){
  return this->sv_total;}

 int get_sv_dim(){
  return this->var_all;}

 int get_sv_count(){
  return this->decision_func->sv_count;}
 
 double* get_alpha(){
  return this->decision_func->alpha;}
 
 float** get_sv(){
  return this->sv;}
 
 float get_rho(){
  return this->decision_func->rho;}
};


void main()
{
 
 //Read Hog feature from XML file
 ///////////////////////////////////////////////////////////////////////////
 printf("1. Feature data xml load\n");
 //create xml to read
 FileStorage read_PositiveXml("C:\\POSCO\\Learned\\Positive1643_64_64.xml", FileStorage::READ);
 FileStorage read_NegativeXml("C:\\POSCO\\Learned\\Negative16064_64_64.xml", FileStorage::READ);
 char SVMSaveFile[100] = "C:\\POSCO\\Learned\\trainedSVM_1643_16064_64_64.xml";
 char SVM_HOGDetectorFile[100] = "C:\\POSCO\\Learned\\HogDetectorXML_1643_16064_64_64.xml";
 //Positive Mat
 Mat pMat; 
 read_PositiveXml["Descriptor_of_images"] >> pMat;
 //Read Row, Cols
 int pRow,pCol;
 pRow = pMat.rows; pCol = pMat.cols;

 //Negative Mat
 Mat nMat;
 read_NegativeXml["Descriptor_of_images"] >> nMat;
 //Read Row, Cols
 int nRow,nCol;
 nRow = nMat.rows; nCol = nMat.cols;

 //Rows, Cols printf
 printf("   pRow=%d pCol=%d, nRow=%d nCol=%d\n", pRow, pCol, nRow, nCol );
 //release
 read_PositiveXml.release();
 //release
 read_NegativeXml.release();
 /////////////////////////////////////////////////////////////////////////////////

 //Make training data for SVM
 /////////////////////////////////////////////////////////////////////////////////
 printf("2. Make training data for SVM\n");
 //descriptor data set
 Mat PN_Descriptor_mtx( pRow + nRow, pCol, CV_32FC1 ); //in here pCol and nCol is descriptor number, so two value must be same;
 memcpy(PN_Descriptor_mtx.data, pMat.data, sizeof(float) * pMat.cols * pMat.rows );
 int startP = sizeof(float) * pMat.cols * pMat.rows;
 memcpy(&(PN_Descriptor_mtx.data[ startP ]), nMat.data, sizeof(float) * nMat.cols * nMat.rows );
 //data labeling
 Mat labels( pRow + nRow, 1, CV_32FC1, Scalar(-1.0) );
    labels.rowRange( 0, pRow ) = Scalar( 1.0 );
 /////////////////////////////////////////////////////////////////////////////////

 //Set svm parameter
 /////////////////////////////////////////////////////////////////////////////////
 printf("4. SVM training\n");
 MySvm svm; //CvSVM svm;
 CvSVMParams params;
 params.svm_type = CvSVM::C_SVC;
    params.kernel_type = CvSVM::LINEAR;
    params.term_crit = cvTermCriteria( CV_TERMCRIT_ITER, 10000, 1e-6 );
 /////////////////////////////////////////////////////////////////////////////////

 //Training
 /////////////////////////////////////////////////////////////////////////////////
 svm.train(PN_Descriptor_mtx, labels, Mat(), Mat(), params);
 //Trained data save
 /////////////////////////////////////////////////////////////////////////////////
 printf("5. SVM xml save\n");
 svm.save( SVMSaveFile );
 
 //////////////////////////////////////////////////////////////////////////////////
 //Second Save option
 //This save file is for Hog.SetSVMDectector() function
 //And if we can use this function(SetSVMDectector), we can use detectMultiScale function.
 //This function is very easy to detect target, and we also can apply GPU option.

 //make firstly, inherited class to access alpha vector and value
 int svmVectorSize = svm.get_support_vector_count();
 int featureSize = pCol;
 //prepare, variables 
 
 
 Mat sv = Mat(svmVectorSize, featureSize, CV_32FC1, 0.0);
 Mat alp = Mat(1, svmVectorSize, CV_32FC1, 0.0);
 Mat re = Mat(1, featureSize, CV_32FC1, 0.0);
 Mat re2 = Mat(1, featureSize+1, CV_32FC1, 0.0);

 
 
 //set value to variables
 for(int i=0; i< svmVectorSize; ++i)
  memcpy( (sv.data + i*featureSize), svm.get_support_vector(i), featureSize*sizeof(float) ); //ok

 
 double * alphaArr = svm.get_alpha();
 int alphaCount = svm.get_alpha_count();

 for(int i=0; i< svmVectorSize; ++i)
 { 
  alp.at< float>(0, i) = (float)alphaArr[i];
  //printf("alpha[%d] = %lf \n", i, (float)alphaArr[i] );
 }
 
 //cvMatMul(alp, sv, re);
 re = alp * sv;

 for(int i=0; i< featureSize; ++i)
  re2.at< float>(0,i) =  re.at< float>(0,i) * -1;
 re2.at< float>(0,featureSize) = svm.get_rho();

 //save to 1d vector to XML format!!
 FileStorage svmSecondXML(SVM_HOGDetectorFile, FileStorage::WRITE);
 svmSecondXML << "SecondSVMd" << re2 ; 

 svmSecondXML.release();
 
 
// FileStorage hogXml("testXML.xml", FileStorage::WRITE); //FileStorage::READ
// write(hogXml, "Data", PN_Descriptor_mtx);
// write(hogXml, "Label", labels);
// hogXml.release();
}



...

To test SVM trained data is whether reliable or not. (example source code)

After training SVM, we should test the trained XML data is reliable or not..

The method to extract HOG feature is refer to -> http://feelmare.blogspot.kr/2014/04/example-source-code-of-extract-hog.html
The method to training SVM of HOG feature is refer to -> http://feelmare.blogspot.kr/2014/04/example-source-code-hog-feature-to.html

The method is using training data.
Again training data make HOG feature, and check the feature is positive or not using trained SVM data.

The example source code is like that.
...
#include < stdio.h>
#include < opencv2\opencv.hpp>
//#include < opencv2\gpu\gpu.hpp>

using namespace cv;
using namespace std;


#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")         
#pragma comment(lib, "opencv_imgproc247d.lib")   //MAT processing        
#pragma comment(lib, "opencv_objdetect247d.lib") //HOGDescriptor
//#pragma comment(lib, "opencv_gpu247d.lib")        
//#pragma comment(lib, "opencv_features2d247d.lib")        
#pragma comment(lib, "opencv_highgui247d.lib")        
#pragma comment(lib, "opencv_ml247d.lib")      
//#pragma comment(lib, "opencv_stitching247d.lib");      
//#pragma comment(lib, "opencv_nonfree247d.lib");      
  
#else        
#pragma comment(lib, "opencv_core247.lib")        
#pragma comment(lib, "opencv_imgproc247.lib")        
#pragma comment(lib, "opencv_objdetect247.lib")        
//#pragma comment(lib, "opencv_gpu247.lib")        
//#pragma comment(lib, "opencv_features2d247.lib")        
#pragma comment(lib, "opencv_highgui247.lib")        
#pragma comment(lib, "opencv_ml247.lib")        
//#pragma comment(lib, "opencv_stitching247.lib");      
//#pragma comment(lib, "opencv_nonfree247.lib");      
#endif 


void main()
{

 //variables
 char FullFileName[100];
 char FirstFileName[100]="./images/upperbody"; //"./NegaImages/Negative";      // 
 int FileNum=96; //262;

 //Load trained SVM xml data
 CvSVM svm;
 svm.load("trainedSVM.xml");

 //count variable
 int nnn=0, ppp=0;

 for(int i=0; i< FileNum; ++i)
 {
  sprintf_s(FullFileName, "%s%d.png", FirstFileName, i+1);
  //printf("%s\n", FullFileName);

  //read image file
  Mat img, img_gray;
  img = imread(FullFileName);
  
  //resizing
  //resize(img, img, Size(16,8) ); //Size(64,48) ); //Size(32*2,16*2)); //Size(80,72) ); 
  resize(img, img, Size(64,48) ); //Size(32*2,16*2)); //Size(80,72) ); 
  //gray
  cvtColor(img, img_gray, CV_RGB2GRAY);

  //Extract HogFeature
  HOGDescriptor d( Size(32,16), Size(8,8), Size(4,4), Size(4,4), 9);
  vector< float> descriptorsValues;
  vector< Point> locations;
  d.compute( img_gray, descriptorsValues, Size(0,0), Size(0,0), locations);
  //vector to Mat
  Mat fm = Mat(descriptorsValues);
  
  //Classification whether data is positive or negative
  int result = svm.predict(fm);
  printf("%s - > %d\n", FullFileName, result);

  //Count data
  if(result == 1)
   ppp++;
  else
   nnn++;

  //show image
  imshow("origin", img);

  waitKey(5);
 }

 printf(" positive/negative = (%d/%d) \n", ppp, nnn);

}
---


Example source code Hog feature to learning by SVM, (SVM, HOGdescriptor)

After extract HOG feature from images, we have to learn for classify data.
This post introduces the method to use machine learning of SVM.

Firstly, you have to prepare postive hog features data and negative hog features data by XML, or TXT, and so on...
The method to get Hog feature, refer to this page -> http://feelmare.blogspot.kr/2014/04/example-source-code-of-extract-hog.html

I already got postive.xml and negative.xml from images.
This example source code learn using SVM from postive.xml, negative.xml.
And save the result fo learning to XML file.

After get SVM trained xml data, we can classify input data whether  positive or not.

This is training source code using SVM.

#include < stdio.h>
#include < opencv2\opencv.hpp>
//#include < opencv2\gpu\gpu.hpp>

using namespace cv;
using namespace std;


#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")         
#pragma comment(lib, "opencv_imgproc247d.lib")   //MAT processing        
#pragma comment(lib, "opencv_objdetect247d.lib") //HOGDescriptor
//#pragma comment(lib, "opencv_gpu247d.lib")        
//#pragma comment(lib, "opencv_features2d247d.lib")        
#pragma comment(lib, "opencv_highgui247d.lib")        
#pragma comment(lib, "opencv_ml247d.lib")      
//#pragma comment(lib, "opencv_stitching247d.lib");      
//#pragma comment(lib, "opencv_nonfree247d.lib");      
  
#else        
#pragma comment(lib, "opencv_core247.lib")        
#pragma comment(lib, "opencv_imgproc247.lib")        
#pragma comment(lib, "opencv_objdetect247.lib")        
//#pragma comment(lib, "opencv_gpu247.lib")        
//#pragma comment(lib, "opencv_features2d247.lib")        
#pragma comment(lib, "opencv_highgui247.lib")        
#pragma comment(lib, "opencv_ml247.lib")        
//#pragma comment(lib, "opencv_stitching247.lib");      
//#pragma comment(lib, "opencv_nonfree247.lib");      
#endif 


void main()
{
 
 //Read Hog feature from XML file
 ///////////////////////////////////////////////////////////////////////////
 printf("1. Feature data xml load\n");
 //create xml to read
 FileStorage read_PositiveXml("Positive.xml", FileStorage::READ);
 FileStorage read_NegativeXml("Negative.xml", FileStorage::READ);

 //Positive Mat
 Mat pMat;
 read_PositiveXml["Descriptor_of_images"] >> pMat;
 //Read Row, Cols
 int pRow,pCol;
 pRow = pMat.rows; pCol = pMat.cols;

 //Negative Mat
 Mat nMat;
 read_NegativeXml["Descriptor_of_images"] >> nMat;
 //Read Row, Cols
 int nRow,nCol;
 nRow = nMat.rows; nCol = nMat.cols;

 //Rows, Cols printf
 printf("   pRow=%d pCol=%d, nRow=%d nCol=%d\n", pRow, pCol, nRow, nCol );
 //release
 read_PositiveXml.release();
 //release
 read_NegativeXml.release();
 /////////////////////////////////////////////////////////////////////////////////

 //Make training data for SVM
 /////////////////////////////////////////////////////////////////////////////////
 printf("2. Make training data for SVM\n");
 //descriptor data set
 Mat PN_Descriptor_mtx( pRow + nRow, pCol, CV_32FC1 ); //in here pCol and nCol is descriptor number, so two value must be same;
 memcpy(PN_Descriptor_mtx.data, pMat.data, sizeof(float) * pMat.cols * pMat.rows );
 int startP = sizeof(float) * pMat.cols * pMat.rows;
 memcpy(&(PN_Descriptor_mtx.data[ startP ]), nMat.data, sizeof(float) * nMat.cols * nMat.rows );
 //data labeling
 Mat labels( pRow + nRow, 1, CV_32FC1, Scalar(-1.0) );
    labels.rowRange( 0, pRow ) = Scalar( 1.0 );
 /////////////////////////////////////////////////////////////////////////////////

 //Set svm parameter
 /////////////////////////////////////////////////////////////////////////////////
 printf("4. SVM training\n");
 CvSVM svm;
 CvSVMParams params;
 params.svm_type = CvSVM::C_SVC;
    params.kernel_type = CvSVM::LINEAR;
    params.term_crit = cvTermCriteria( CV_TERMCRIT_ITER, 10000, 1e-6 );
 /////////////////////////////////////////////////////////////////////////////////

 //Training
 /////////////////////////////////////////////////////////////////////////////////
 svm.train(PN_Descriptor_mtx, labels, Mat(), Mat(), params);

 //Trained data save
 /////////////////////////////////////////////////////////////////////////////////
 printf("5. SVM xml save\n");
 svm.save( "trainedSVM.xml" );
 
// FileStorage hogXml("testXML.xml", FileStorage::WRITE); //FileStorage::READ
// write(hogXml, "Data", PN_Descriptor_mtx);
// write(hogXml, "Label", labels);
// hogXml.release();
}
---

After learning, the method to classify is refer to http://feelmare.blogspot.kr/2014/04/to-test-svm-trained-data-is-whether.html

Example source code of extract HOG feature from images, save descriptor values to xml file, using opencv (using HOGDescriptor )

This example source code is to extract HOG feature from images.
And save descriptors to XML file.

The source code explain how to use HOGDescriptor function.



..
#include < stdio.h>
#include < opencv2\opencv.hpp>
//#include < opencv2\gpu\gpu.hpp>

using namespace cv;
using namespace std;


#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")         
#pragma comment(lib, "opencv_imgproc247d.lib")   //MAT processing        
#pragma comment(lib, "opencv_objdetect247d.lib") //HOGDescriptor
//#pragma comment(lib, "opencv_gpu247d.lib")        
//#pragma comment(lib, "opencv_features2d247d.lib")        
#pragma comment(lib, "opencv_highgui247d.lib")        
//#pragma comment(lib, "opencv_ml247d.lib")      
//#pragma comment(lib, "opencv_stitching247d.lib");      
//#pragma comment(lib, "opencv_nonfree247d.lib");      
  
#else        
#pragma comment(lib, "opencv_core247.lib")        
#pragma comment(lib, "opencv_imgproc247.lib")        
#pragma comment(lib, "opencv_objdetect247.lib")        
//#pragma comment(lib, "opencv_gpu247.lib")        
//#pragma comment(lib, "opencv_features2d247.lib")        
#pragma comment(lib, "opencv_highgui247.lib")        
//#pragma comment(lib, "opencv_ml247.lib")        
//#pragma comment(lib, "opencv_stitching247.lib");      
//#pragma comment(lib, "opencv_nonfree247.lib");      
#endif 


void main()
{
 //variables
 char FullFileName[100];
 char FirstFileName[100]="./images/upperbody";
 char SaveHogDesFileName[100] = "Positive.xml";
 int FileNum=96;

 vector< vector < float> > v_descriptorsValues;
 vector< vector < Point> > v_locations;


 for(int i=0; i< FileNum; ++i)
 {
  sprintf_s(FullFileName, "%s%d.png", FirstFileName, i+1);
  printf("%s\n", FullFileName);

  //read image file
  Mat img, img_gray;
  img = imread(FullFileName);
  
  //resizing
  resize(img, img, Size(64,48) ); //Size(64,48) ); //Size(32*2,16*2)); //Size(80,72) ); 
  //gray
  cvtColor(img, img_gray, CV_RGB2GRAY);

  //extract feature
  HOGDescriptor d( Size(32,16), Size(8,8), Size(4,4), Size(4,4), 9);
  vector< float> descriptorsValues;
  vector< Point> locations;
  d.compute( img_gray, descriptorsValues, Size(0,0), Size(0,0), locations);

  //printf("descriptor number =%d\n", descriptorsValues.size() );
  v_descriptorsValues.push_back( descriptorsValues );
  v_locations.push_back( locations );
  //show image
  imshow("origin", img);

  waitKey(5);
 }

 //refer to this address -> http://feelmare.blogspot.kr/2014/04/the-example-source-code-of-2d-vector.html
 //save to xml
 FileStorage hogXml(SaveHogDesFileName, FileStorage::WRITE); //FileStorage::READ
 //2d vector to Mat
 int row=v_descriptorsValues.size(), col=v_descriptorsValues[0].size();
 printf("col=%d, row=%d\n", row, col);
 Mat M(row,col,CV_32F);
 //save Mat to XML
 for(int i=0; i< row; ++i)  
  memcpy( &(M.data[col * i * sizeof(float) ]) ,v_descriptorsValues[i].data(),col*sizeof(float));
 //write xml
 write(hogXml, "Descriptor_of_images",  M);

 //write(hogXml, "Descriptor", v_descriptorsValues );
 //write(hogXml, "locations", v_locations );
 hogXml.release();

}



...


same with above code.
< gist code start>

< gist code end >