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 :/