none
C++로 SVM을 구동하려하는데 오류가 납니다...도와주세요.. RRS feed

  • 질문

  • visual studio 2015를 사용하고 있고 opencv(2.4.13)를 사용하고 있습니다.

    우선 코드는 아래와 같습니다.

    #include <iostream>
    #include <opencv2/opencv.hpp>

    using namespace cv;
    using namespace std;
    bool plotSupportVectors = true;
     int numTrainingPoints = 200;
     int numTestPoints = 4000;
     int a_size = 200;
     int eq = 2;

     //정확도 평가
     float evaluate(Mat& predicted, Mat& actual) {
    assert(predicted.rows == actual.rows);
    int t = 0;
    int f = 0;
    for (int i = 0; i < actual.rows; i++) {
    float p = predicted.at<float>(i,0);
    float a = actual.at<float>(i, 0);
    if ((p >= 0.0&& a >= 0.0) || (p <= 0.0&& a <= 0.0))
    t++;
    else
    f++;
    }
    return (t * 1.0) / (t + f);
     
     }


    //차트 그리기
    void plot_binary(Mat& data, Mat& classes, string name) {
    Mat plot(a_size, a_size, CV_8UC3);
    plot.setTo(Scalar(255.0, 255.0, 255.0));
    for (int i = 0; i < data.rows; i++) {
    float x = data.at<float>(i, 0)*a_size;
    float y = data.at<float>(i, 1)*a_size;
    if (classes.at<float>(i,0)>0)
    circle(plot, Point(x, y), 2, CV_RGB(255, 0, 0), 1);
    else
    circle(plot, Point(x, y), 2, CV_RGB(0, 255, 0), 1);
    }
    imshow(name, plot);
    }

    //학습데이터 생성
    int f(float x, float y, int equation) {
    switch (equation) {
    case 0:
    return y > sin(x * 10) ? -1 : 1;
    break;
    case 1:
    return y > cos(x * 10) ? -1 : 1;
    break;
    case 2:
    return y > 2*x ? -1 : 1;
    break;
    case 3:
    return y > tan(x * 10) ? -1 : 1;
    break;
    default:
    return y > cos(x * 10) ? -1 : 1;

    }

    }

    //라벨 데이터
    Mat labelData(Mat points, int equation) {

    Mat labels(points.rows, 1, CV_32FC1);
    for (int i = 0; i < points.rows; i++) {
    float x = points.at<float>(i, 0);
    float y = points.at<float>(i, 1);
    labels.at<float>(i, 0) = f(x, y, equation);
    }
    return labels;
    }
    void svm(Mat& trainingData, Mat& trainingClasses, Mat& testData, Mat& testClasses) {
    CvSVMParams param = CvSVMParams();
    param.svm_type = CvSVM::C_SVC;
    param.kernel_type = CvSVM::RBF;
    param.degree = 0;
    param.gamma = 20;
    param.coef0 = 0;
    param.C = 7;
    param.nu = 0.0;
    param.p = 0.0;
    param.class_weights = NULL;
    param.term_crit.type = CV_TERMCRIT_EPS * CV_TERMCRIT_EPS;
    param.term_crit.max_iter = 1000;
    param.term_crit.epsilon = 1e-6;

    CvSVM svm(trainingData, trainingClasses, Mat(), Mat(), param);
    Mat predicted(testClasses.rows, 1, CV_32F);
    for (int i = 0; i < testClasses.rows; i++) {
    Mat sample = testData.row(i);
    float x = sample.at<float>(0, 0);
    float y = sample.at<float>(0, 1);
    predicted.at<float>(i, 0) = svm.predict(sample);
    }
    cout << "Accuracy_{SVM} = " << evaluate(predicted, testClasses) << endl;
    plot_binary(testData, predicted, "Predictions SVM ");

    if (plotSupportVectors) {
    Mat plot_sv(a_size, a_size, CV_8UC3);
    plot_sv.setTo(Scalar(255.0, 255.0, 255.0));
    int svec_count = svm.get_support_vector_count();
    for (int vecNum = 0; vecNum < svec_count; vecNum++) {
    const float *vec = svm.get_support_vector(vecNum);
    circle(plot_sv, Point(vec[0] * a_size, vec[1] * a_size), 3, CV_RGB(0, 0, 0));
    }
    imshow(" Support Vector ", plot_sv);
    }

    }


    int main() {
    Mat trainingData(numTrainingPoints, 2, CV_32FC1);
    Mat testData(numTestPoints, 2, CV_32FC1);
    randu(trainingData, 0, 1);
    randu(testData, 0, 1);
    Mat trainingClasses = labelData(trainingData, eq);
    Mat testClasses = labelData(testData, eq);
    plot_binary(trainingData, trainingClasses, " Training Data");
    plot_binary(testData, testClasses, " Test Data");

    svm(trainingData, trainingClasses, testData, testClasses);

    waitKey();
    return 0;
    }

    이 코드를 돌려보면 

    abort() has been called 라는 에러 창이 뜨면서 멈춰버립니다.

    debug를 실행하여 중단점을 찾아보면 

    return EXCEPTION_CONTINUE_SEARCH;   로뜹니다.

    break point를 잡아 에러가 나는 부분을 찾아보면 

    void svm 함수 안의 

    CvSVM svm(trainingData, trainingClasses, Mat(), Mat(), param); 인것을 확인했습니다.

    처리되지 않은 예외 발생: Microsoft C++ 예외: cv::Exception  이라고뜨며

    콘솔창에는

    OpenCV Error: Bad argument (Unknown type of term criteria) in cvCheckTermCriteria, file C:\builds\2_4_PackSlave-win32-vc12-shared\opencv\modules\core\src\array.coo line 3154  라고뜹니다.

    도와주시면 정말 감사 하겠습니다..ㅠㅠ...

    2017년 3월 15일 수요일 오전 8:05