SVM OpenCV c ++ Predict не возвращает ничего, кроме 1

Я считаю, что я успешно обучил SVM, но когда я пытаюсь предсказать с его помощью, вывод целиком 1.

Мой код для обучения выглядит так:

for(size_t i = 0; i < (testPosArraySize); i++){
testGivenImg = imread(imagePosDir[i]);
detector->detect(testGivenImg, testKeypointsPos);
bowDE.compute(testGivenImg, testKeypointsPos, testFeaturesPos);
testFeaturesPos.reshape(1, 1);
testFeaturesVec.push_back(testFeaturesPos);
}
for(size_t i = 0; i < (testNegaArraySize); i++){
testGivenImg = imread(image[i]);
detector->detect(testGivenImg, testKeypointsNega);
bowDE.compute(testGivenImg, testKeypointsNega, testFeaturesNega);
testFeaturesNega.reshape(1, 1);
testFeaturesVec.push_back(testFeaturesNega);
}

Mat labels(numSamples, 1, CV_32F);
labels.rowRange(0, testPosArraySize).setTo(1);
labels.rowRange(testPosArraySize + 1, numSamples).setTo(-1);
SVM.model.train(fileTestFeat, labels, Mat(), Mat(), SVMParams());

Мой код для предсказания выглядит так:

vector<Mat> predictMatVec(predictArraySize); // -- amount of testing images

for(size_t i = 0; i < (predictArraySize); i++){
predictImg = imread(imageNegaDir[i]);
detector->detect(predictImg, predictKeypoints);
bowDE.compute(predictImg, predictKeypoints, predictFeatures);
predictFeatures.reshape(1, 1);
predictMatVec[i].push_back(predictFeatures);

Mat predictMat = Mat(predictMatVec);
float* predictFloat1D = (float*)predictMat.data;
Mat predictMat1D(1, fileTestFeat.cols, CV_32FC1, predictFloat1D);
float predictFloat = model.predict(predictMat1D);
cout << " -- SVM output: " << predictFloat << endl;
}

Но он не возвращает ничего, кроме 1.

введите описание изображения здесь

Что с этим не так?

3

Решение

Таким образом, словарь уже создан (например, BOWKMeansTrainer) и вы начинаете тренировать свой классификатор SVM, верно?

На этом этапе у вас есть детектор признаков, экстрактор, средство сравнения и экстрактор дескриптора изображения BOW (для вычисления дескриптора изображения с использованием пакета визуальных слов), такие как:

cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create("SURF");
cv::Ptr<cv::DescriptorExtractor> extractor = cv::DescriptorExtractor::create("SURF");
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("BruteForce ");

cv::BOWImgDescriptorExtractor bowide(extractor, matcher);
bowide->setVocabulary(vocabulary);

Прежде всего нам нужно найти набор тренировок для наших гистограмм:

cv::Mat samples;
cv::Mat labels(0, 1, CV_32FC1);

for(auto& it : imagePosDir)
{
cv::Mat image = cv::imread(it);

std::vector<cv::KeyPoint> keypoints;
detector->detect(image, keypoints);

if(keypoints.empty()) continue;

// Responses to the vocabulary
cv::Mat imgDescriptor;
bowide.compute(image, keypoints, imgDescriptor);

if(imgDescriptor.empty()) continue;

if(samples.empty())
{
samples.create(0, imgDescriptor.cols, imgDescriptor.type());
}

// Copy class samples and labels
std::cout << "Adding " << imgDescriptor.rows << " positive sample." << std::endl;
samples.push_back(imgDescriptor);

cv::Mat classLabels = cv::Mat::ones(imgDescriptor.rows, 1, CV_32FC1);
labels.push_back(classLabels);
}

Сделать то же самое для imagePosNeg Кроме этого classLabels будет иметь нулевые значения, такие как:

...
cv::Mat classLabels = cv::Mat::zeros(imgDescriptor.rows, 1, CV_32FC1);
labels.push_back(classLabels);
...

Обратите внимание, как я строю образцы и метки, я пометил положительные образцы метками «1», а затем негативы меткой «0». Таким образом, у нас есть данные обучения для каждого класса (здесь для положительных и отрицательных) в samples, Давайте пройдем обучение:

cv::Mat samples_32f;
samples.convertTo(samples_32f, CV_32F);

CvSVM svm;
svm.train(samples_32f, labels);
// Do something with the classifier, like saving it to file

Затем тестирование давайте проведем тестирование классификатора:

for(auto& it : testDir)
{
cv::Mat image = cv::imread(it);

std::vector<cv::KeyPoint> keypoints;
detector->detect(image, keypoints);

if(keypoints.empty()) continue;

// Responses to the vocabulary
cv::Mat imgDescriptor;
bowide.compute(image, keypoints, imgDescriptor);

if(imgDescriptor.empty()) continue;

float res = svm.predict(imgDescriptor, true);

std::cout << "- Result of prediction: " << res << std::endl;
}

Работает?


Обновление № 1:

Здесь я сделал простой пример с BOW + SVM под OpenCV 3.0:
https://github.com/bkornel/OpenCV_BOW_SVM/blob/master/main.cpp

Это хорошо работает для классификации бутылок кока-колы / пепси. Я также опубликовал двоичные файлы, чтобы вы могли попробовать свою базу данных. Надеюсь, что это работает 🙂

2

Другие решения


По вопросам рекламы [email protected]