Moim zadaniem jest wytrenować własnego SVM i użycie go do detekcji np. konkretnej osoby/konkretnego przedmiotu na filmie.
Wydaje mi się, że moja koncepcja i kod z trenowaniem SVM jest poprawna (daje około 200 "positive samples" i ok. 1400 "negative samples"). Wszystkie przykłady są w wymiarach 64x128. Po trenowaniu uzyskuję plik z wytrenowanym SVM (nie do końca wiem, na co w nim patrzeć ale ilość kolumn/wierszy oraz liczby wydają się być poprawne i takie jakich oczekuję. Nie jestem pewny jak ładować mój SVM do HOG-a ale też nie widzę w kodzie błędu. Kompilator odpala program jednak na filmie który testuje zostaje wykryte wszystko a nie to do czego został wytrenowany (tak jakby SVM się nie uczył tego co mu się daje albo jakby nie został poprawnie wczytany do HOG-a). Poniżej mój kod:
Stworzenie trainData:
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;
}
Tworzenie wektoru cech z podanego obrazka:
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;
}
Tutaj jest jak go trenuje:
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;
}
Przepraszam, że umieszcza tak dużo kodu ale naprawdę nie mam pojęcia co robię źle. Raczej wydaje mi się, że problem jest z trenowaniem chociaż nie jestem pewny. Mogę też umieścić w jaki sposób wczytuje SVM do HOG-a ale najpierw chciałbym się upewnić, że trenowanie przebiega pomyślnie.
Co myślicie? Macie jakieś spostrzeżenia? Naprawdę nie mam pojęcia co dokładnie jest źle i czym się zająć. Dla mnie wygląda wszystko poprawnie.
Za wszystkie rady, odpowiedzi i spostrzeżenia będę bardzo wdzięczny bo poprawiam kod już 3 dzień i wciąż bez efektów :/