Trained SVM doesn't work

asked 2018-07-29 02:50:04 -0500

Macmik gravatar image

I want train my own SVM and use it to detect some objects, for example dogs.

I think I train and save SVM correctly (XML file seems fine) but when I want test it on some film it detects everything and it doesn't find correct objects.

Here is how I train svm:

void FeatureExtractor::computeTrainingData(const std::string &folderPositive, const std::string &folderNegative)
{
std::string format = "png";

std::string fPositive = "../" + folderPositive + "/*." + format;
std::vector<cv::String>filenamesPositive;
cv::glob(fPositive, filenamesPositive);
int sizePositive = filenamesPositive.size();

std::string fNegative = "../" + folderNegative + "/*." + format;
std::vector<cv::String> filenamesNegative;
cv::glob(fNegative, filenamesNegative);
int sizeNegative = filenamesNegative.size();

trainingData = cv::Mat(0, 3780, CV_32FC1);
labels = cv::Mat(sizePositive + sizeNegative, 1, CV_32S);
std::clog << "Easy, I am working now...";
for (int i = 0; i < sizePositive; i++)
{

    trainingData.push_back(cv::Mat(calculateFeatures(filenamesPositive[i]), true).reshape(1, 1));
    labels.at<float>(i, 0) = 1;
}

for (int i = 0; i < sizeNegative; i++)
{
    trainingData.push_back(cv::Mat(calculateFeatures(filenamesNegative[i]), true).reshape(1, 1));
    labels.at<float>(i+sizePositive, 0) = -1;
}


std::clog<<"[done]" << std::endl;
}

Create Features vector:

std::vector<float> FeatureExtractor::calculateFeatures(const std::string &filename)
{

cv::Mat image = cv::imread(filename);
if (image.cols != 64 || image.rows != 128)
    std::cout << "Wrong image size" << std::endl;
std::vector<float> featureVector;
hog.compute(image, featureVector);
return featureVector;
}

And here is how I train it:

void FeatureExtractor::trainAndSaveSVM(std::string &&filename)
{
std::cout << "Entering trainAndSave" << std::endl;

cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
svm->setType(cv::ml::SVM::C_SVC);
svm->setKernel(cv::ml::SVM::LINEAR);
//svm->setGamma(3);
std::cout << "Creating SVM pointer successfull" << std::endl;

cv::Ptr<cv::ml::TrainData> tData = cv::ml::TrainData::create(trainingData, cv::ml::SampleTypes::ROW_SAMPLE, labels);

std::clog << "Wait until training will get finish! This may take a few minutes...";
svm->trainAuto(tData);
std::clog << "...[done]" << std::endl;
std::cout << "trainAuto successfull" << std::endl;

svm->save(filename);
std::cout << "saving to file successfull" << std::endl;

}

What do you think? What am I doing wrong? I put about 200 positive samples and about 1300 negative samples. Pictures are 64x128. I will be grateful for all the advices.

edit retag flag offensive close merge delete

Comments

No, -1 when it is negative sample and 1 when it is positive sample. I checked it xml file and this part is fine

Macmik gravatar imageMacmik ( 2018-07-29 13:02:10 -0500 )edit

Hi, can you check this line trainingData = cv::Mat(0, 3780, CV_32FC1); The row should be 1.

vps gravatar imagevps ( 2018-07-30 07:07:51 -0500 )edit

Hmm maybe you are right but then I get some error here:

cv::Ptr<cv::ml::TrainData> tData = cv::ml::TrainData::create(trainingData, cv::ml::SampleTypes::ROW_SAMPLE, labels);
Macmik gravatar imageMacmik ( 2018-07-30 15:46:44 -0500 )edit