Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

In OpenCV, there's undocumented API

HOGDescriptor::compute(const cv::Mat &img, vector<float> &descriptors)

which you could pass in your image, and retrieve the descriptors for it. And then you could construct a large feature matrix containing both positive and negative features, and also label matrix that specifies which entry in that feature matrix is positive or negative.

Both the features and label matrices then could be passed into CvSVM class for training, and you could save it in HDD and load it afterwards. Later on you could extract features from a patch of an image, use compute to extract the features, and pass it into svm.predict to obtain the prediction whether it's positive or negative image. The downside from this is that you need to apply your own detection window algorithm, etc.

Below is some sample code to train your own SVM.

Mat labels( pos_count + neg_count, 1, CV_32FC1, Scalar(-1.0) );
labels.rowRange( 0, pos_count ) = Scalar( 1.0 );

CvSVM svm;
CvSVMParams params;
params.C = c;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria( CV_TERMCRIT_ITER, 10000, 1e-6 );

Mat feat_matrix( pos_count + neg_count, pos_feats[0].cols, pos_feats[0].type() );
for( int i = 0; i < pos_count; i++ )
    pos_feats[i].copyTo( feat_matrix.rowRange(i, i+1) );
for( int i = 0; i < neg_count; i++ )
    neg_feats[i].copyTo( feat_matrix.rowRange(i + pos_count, i + pos_count + 1) );

cout << "Start training SVM" << endl;
svm.train( feat_matrix, labels, Mat(), Mat(), params );
svm.save( (path + svm_file).c_str() );

Mat labels( pos_count + neg_count, 1, CV_32FC1, Scalar(-1.0) );
labels.rowRange( 0, pos_count ) = Scalar( 1.0 );

CvSVM svm;
CvSVMParams params;
params.C = 0.001; /* soft margin SVM */
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria( CV_TERMCRIT_ITER, 10000, 1e-6 );

Mat feat_matrix( pos_count + neg_count, pos_feats[0].cols, pos_feats[0].type() );
for( int i = 0; i < pos_count; i++ )
    pos_feats[i].copyTo( feat_matrix.rowRange(i, i+1) );
for( int i = 0; i < neg_count; i++ )
    neg_feats[i].copyTo( feat_matrix.rowRange(i + pos_count, i + pos_count + 1) );

cout << "Start training SVM" << endl;
svm.train( feat_matrix, labels, Mat(), Mat(), params );
svm.save( "my_svm_file" );

In OpenCV, there's undocumented API

HOGDescriptor::compute(const cv::Mat &img, vector<float> &descriptors)

which you could pass in your image, and retrieve the descriptors for it. And then you could construct a large feature matrix containing both positive and negative features, and also label matrix that specifies which entry in that feature matrix is positive or negative.

Both the features and label matrices then could be passed into CvSVM class for training, and you could save it in HDD and load it afterwards. Later on you could extract features from a patch of an image, use compute to extract the features, and pass it into svm.predict to obtain the prediction whether it's positive or negative image. The downside from this is that you need to apply your own detection window algorithm, etc.

Below is some sample code to train your own SVM.

Mat labels( pos_count + neg_count, 1, CV_32FC1, Scalar(-1.0) );
labels.rowRange( 0, pos_count ) = Scalar( 1.0 );

CvSVM svm;
CvSVMParams params;
params.C = c;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria( CV_TERMCRIT_ITER, 10000, 1e-6 );

Mat feat_matrix( pos_count + neg_count, pos_feats[0].cols, pos_feats[0].type() );
for( int i = 0; i < pos_count; i++ )
    pos_feats[i].copyTo( feat_matrix.rowRange(i, i+1) );
for( int i = 0; i < neg_count; i++ )
    neg_feats[i].copyTo( feat_matrix.rowRange(i + pos_count, i + pos_count + 1) );

cout << "Start training SVM" << endl;
svm.train( feat_matrix, labels, Mat(), Mat(), params );
svm.save( (path + svm_file).c_str() );

Mat labels( pos_count + neg_count, 1, CV_32FC1, Scalar(-1.0) );
labels.rowRange( 0, pos_count ) = Scalar( 1.0 );

CvSVM svm;
CvSVMParams params;
params.C = 0.001; /* soft margin SVM */
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria( CV_TERMCRIT_ITER, 10000, 1e-6 );

Mat feat_matrix( pos_count + neg_count, pos_feats[0].cols, pos_feats[0].type() );
for( int i = 0; i < pos_count; i++ )
    pos_feats[i].copyTo( feat_matrix.rowRange(i, i+1) );
for( int i = 0; i < neg_count; i++ )
    neg_feats[i].copyTo( feat_matrix.rowRange(i + pos_count, i + pos_count + 1) );

cout << "Start training SVM" << endl;
svm.train( feat_matrix, labels, Mat(), Mat(), params );
svm.save( "my_svm_file" );