【问题标题】:SVM training issue for a simple dataset (Opencv 2.4.9)简单数据集的 SVM 训练问题 (Opencv 2.4.9)
【发布时间】:2016-10-29 10:28:36
【问题描述】:

我正在尝试一个简单的示例来学习 OpenCV 中的 SVM,但训练后我没有得到正确的支持向量。需要一些帮助来理解这个问题。 我的代码是:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>

using namespace cv;
using namespace std;

int main() {

Mat frame(Size(640,360), CV_8UC3, Scalar::all(255));
float train[15][2] = { {296, 296}, {296, 312}, {312,   8}, {312,  56}, {312,  88}, {328,  88}, {328, 104}, {328, 264}, {344,   8}, {344,  40}, {360,   8}, {360,  56}, {376,   8}, {376,  40}, {376,  56} };
Mat trainingDataMat(15, 2, CV_32FC1, train);
float labels[15] = { -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1 };
Mat labelsMat(15, 1, CV_32FC1, labels);

CvSVMParams param;
param.svm_type     = CvSVM::C_SVC;
param.C            = 0.1;
param.kernel_type  = SVM::LINEAR;
param.term_crit    = TermCriteria(CV_TERMCRIT_ITER, 1000, 1e-6);

CvSVM SVM;

SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), param);
cout<< "Training Finished..." << endl;
for(int i = 0; i < frame.rows; ++i) {
    for(int j = 0; j < frame.cols; ++j) {
        Mat sampleMat = (Mat_<float>(1,2) << i,j);
        float response = SVM.predict(sampleMat);
        //cout << response << endl;
        if(response == 1) {
            frame.at<Vec3b>(i,j)[2] = 0;
        } else {
            frame.at<Vec3b>(i,j)[0] = 0;
        }
    }
}
for(int dis = 0; dis < trainingDataMat.rows; dis++) {
    if(labels[dis] == 1) {
        circle(frame, Point((int)train[dis][0], (int)train[dis][1]), 3, Scalar (0, 0, 0), -1);
    } else {
        circle(frame, Point((int)train[dis][0], (int)train[dis][1]), 3, Scalar (0, 255, 0), -1);
    }
}    
int n = SVM.get_support_vector_count();
for(int i = 0; i < n; i++) {
          const float* v = SVM.get_support_vector(i);
          cout << "support Vectors : " << v[0] << " " << v[1] <<endl;
          circle(frame,Point((int)v[0], (int)v[1]), 6, Scalar(128, 128, 128), 2, 8);
}
imwrite("frame.jpg",frame);
imshow("output", frame);
waitKey(0);

return 0;
}

Output image is attached

SVM 行没有像我预期的那样将两个类分开。

支持向量的结果是

 support Vectors : 0 0.0125

【问题讨论】:

    标签: c++ opencv svm libsvm


    【解决方案1】:

    SVM 应该没问题。我认为问题在于您的显示器。当你打电话给你的circle(frame, Point((int)train[dis][0], (int)train[dis][1]), 3, Scalar (0, 0, 0), -1); 时,OpenCV 知道你想要在行号train[dis][1] 和列号train[dis][0] 中的一个圆圈。这不是您想要的,因为 OpenCV 的一个特点是它对矩阵和点使用不同的坐标系。 image.at&lt;float&gt;(Point(i,j)) 等价于 image.at&lt;float&gt;(j,i)

    尝试将您的 circle 电话替换为:

    if(labels[dis] == 1) {
        circle(frame, Point((int)train[dis][1], (int)train[dis][0]), 3, Scalar (0, 0, 0), -1);
    } else {
        circle(frame, Point((int)train[dis][1], (int)train[dis][0]), 3, Scalar (0, 255, 0), -1);
    }
    

    【讨论】:

    • 谢谢@Sunreef,它有帮助,但我仍然得到了支持向量,support Vectors : 0.0125 0
    • 这对我来说似乎并不那么荒谬,因为你的两组之间的分离是垂直的(因此法线向量应该是 x =/= 0 和 y = 0)。 @venkatsubramanian
    • 我正在使用 Opencv 2.4.9,我尝试了 src 文件中的 SVM 示例 (non_linear_svms.cpp),我得到的支持向量为 @987654331 @, 这是正确的吗?还是Opencv错误?,我的输出图像是drive.google.com/file/d/0BzXZDZFGar7BdVBUekthYm1yVlk/view左上角绘制了支持向量,opencv文档中的输出是docs.opencv.org/2.4/_images/result1.png,我的图像和opencv的示例图像之间的区别是缺少支持向量点标记
    猜你喜欢
    • 2015-08-14
    • 2015-09-26
    • 2016-01-22
    • 2015-05-04
    • 2015-07-25
    • 2015-04-18
    • 2015-01-22
    • 2014-05-18
    相关资源
    最近更新 更多