I am trying to use SVM for object detection with c++. I am following this answer . I am facing one problem that CvSVM is not used as of now. So I have modified the training code as follows.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace cv::ml;
int main()
{
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
// Set up training data
float labels[4] = {1.0, -1.0, -1.0, -1.0};
Mat labelsMat(4, 1, CV_32FC1, labels);
float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
Mat trainingDataMat(4, 2, CV_32FC1, trainingData);
// Set up SVM's parameters
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::LINEAR);
//svm.term_crit = SVM::getTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
// Train the SVM
//Ptr<SVM> svm1 = SVM::trainAuto();
SVM->train(trainingDataMat, labelsMat, Mat(), Mat(), svm);
Vec3b green(0,255,0), blue (255,0,0);
// 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) << j,i);
float response = svm->predict(sampleMat);
if (response == 1)
image.at<Vec3b>(i,j) = green;
else if (response == -1)
image.at<Vec3b>(i,j) = blue;
}
// Show the training data
int thickness = -1;
int lineType = 8;
circle( image, Point(501, 10), 5, Scalar( 0, 0, 0), thickness, lineType);
circle( image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType);
circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);
circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType);
// Show support vectors
thickness = 2;
lineType = 8;
int c = SVM.get_support_vector_count();
for (int i = 0; i < c; ++i)
{
const float* v = SVM.get_support_vector(i);
circle( image, Point( (int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thickness, lineType);
}
imwrite("result.png", image); // save the image
imshow("SVM Simple Example", image); // show it to the user
waitKey(0);
}
I am not able to implement the train function. It says that the function is not found. Please help me out with a newer version of this code.
You have several errors in your code. Some are C++ syntactic errors, some are due the fact that you are using OpenCV 2.4.X api, which is different from OpenCV 3.0
1) When you are referring to the svm instance, you should use svm
(the variable name), not SVM
the class name.
2) In the case of classification problem the responses must be categorical. So
float labels[4] = { 1.0, -1.0, -1.0, -1.0 };
Mat labelsMat(4, 1, CV_32FC1, labels);
should be:
int labels[4] = { 1, -1, -1, -1 };
Mat labelsMat(4, 1, CV_32SC1, labels);
3) train
accepts different parameters. SVM->train(trainingDataMat, labelsMat, Mat(), Mat(), svm);
should be: svm->train(trainingDataMat, ROW_SAMPLE, labelsMat);
4) get_support_vector_count
doesn't exists in OpenCV 3.0. int c = SVM.get_support_vector_count();
should be: int c = svm->getSupportVectors().rows;
5) get_support_vector
doesn't exists in OpenCV 3.0. const float* v = SVM.get_support_vector(i);
should be: const float* v = svm->getSupportVectors().ptr<float>(i);
The code in this answer already works as expected. If you introduce such errors it won't work, obviously.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.