Я попытался запустить пример проекта SVM SVM официального OpenCV документация, но показалось, что код для openCV версии 3.0.0 устарел.
Поэтому я скорректировал код с помощью этой записи stackoverflow и получил следующий код:
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
// Set up training data
int labels[4] = { 1.0, -1.0, -1.0, -1.0 };
Mat labelsMat(4, 1, CV_32S, labels);
int trainingData[4][2] = { { 501, 10 },{ 255, 10 }, { 501, 255 }, { 10, 501 } };
Mat trainingDataMat(4, 2, CV_32F, trainingData);
// Set up SVM's parameters
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::LINEAR);
svm->setTermCriteria(TermCriteria(CV_TERMCRIT_ITER, 100, 1e-6));
Ptr<TrainData> trainData = TrainData::create(trainingDataMat, ml::ROW_SAMPLE, labelsMat);
// Train the SVM
//svm->trainAuto(trainData);
svm->train(trainingDataMat, ml::ROW_SAMPLE, labelsMat);
Vec3b green(0, 255, 0), blue(255, 0, 0), red(0, 0 ,255), yellow(0, 255, 255);
// Show the decision regions given by the SVM
for (int i = 0; i < image.rows; ++i)
for (int j = 0; j < image.cols; ++j)
{
Mat sampleMat = (Mat_<float>(1, 2) << i, j);
Mat result;
svm->predict(sampleMat, result);
float response = result.at<float>(0);
if (response == 1)
image.at<Vec3b>(i, j) = green;
else if (response == -1)
image.at<Vec3b>(i, j) = blue;
else if (response == 2)
image.at<Vec3b>(i, j) = red;
else if (response == -2)
image.at<Vec3b>(i, j) = yellow;
//else return 0;
}
Теперь код хотя бы работает без исключений, но все равно не работает.
При использовании метода TrainingData::create
в сочетании с svm->trainAuto(trainData)
я просто получаю черное изображение ( predict
всегда возвращает 0 ).
Если я использую svm->train(trainingDataMat, ml::ROW_SAMPLE, labelsMat)
, я получаю изображение, в котором каждый пиксель имеет один и тот же цвет (predict
всегда возвращает одно и то же значение). С метками, установленными, как указано выше, изображение будет полностью синим.
Я действительно не вижу, что я мог сделать неправильно.