Hi everyone. I have a project which bases on training my own SVM to detect particular silhouette. I wrote some code but it doesn't work so I want to be sure that I did everything ok. I want also mention that I am new in OpenCV world so sorry if I write some silly things but here is how I imagine it:
1) First of all, I collect some materials to train. I create two folders with some positive samples (my silhouette to detect - just about 200 samples) and negative folder (everything different - about 1300 samples). Pictures are 64x128.
2) The second step is to create a feature vector of each sample. Here I am not sure which information from the picture is important. In my case, I use HOG on my pictures and put gradient of each pixel to feature vector but maybe it is better to take for example H value from HSV picture? Here is some code:
std::vector<float> featureVector;
hog.compute(image, featureVector);
3) I creat Mat to keep all of this vectors. 1 row = 1 feature vector. So for example when I have 1500 samples then I got matrix with 1500 rows. This is how I do it:
trainingData = cv::Mat::ones(sizePositive + sizeNegative, 3780, CV_32FC1);
labels = cv::Mat::zeros(sizePositive + sizeNegative, 1, CV_32S);
for (int i = 0; i < sizePositive; i++)
{
for (int j = 0; j < 3780; j++)
{
trainingData.at<float>(i, j) = features[j];
}
labels.at<float>(i, 0) = 1;
}
for (int i = 0; i < sizeNegative; i++)
{
std::vector<float> features = calculateFeatures(filenamesNegative[i]);
for (int j = 0; j < 3780; j++)
{
trainingData.at<float>(i+sizePositive, j) = features[j];
}
labels.at<float>(i+sizePositive, 0) = -1;
}
In this step, I also create labels matrix and put 1 when it is a positive sample and -1 when it is a negative sample.
4) After this, I am ready to train? I have trainingData with my features vectors and my labels which defines which sample was positive and which was negative. ( I checked XML files with my labels and trainingData and they look fine). Here is how I train my SVM:
cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
// set the parameters
svm->setType(cv::ml::SVM::C_SVC);
svm->setKernel(cv::ml::SVM::RBF);
// create training data object
cv::Ptr<cv::ml::TrainData> tData = cv::ml::TrainData::create(trainingData, cv::ml::SampleTypes::ROW_SAMPLE, labels);
// train svm to optimal parameters using opencv autotraining
svm->trainAuto(tData);
What do you think? It is good thinking? I am doing something wrong? Because it seems that this SVM doesn't learn anything :/ I will be very grateful for your help and some advice.