Ask Your Question
0

OpenCV undefined reference CvSVM::predict, maybe it is a bug , please check it.

asked 2013-09-27 19:18:15 -0500

zszhong gravatar image

updated 2013-09-27 19:21:19 -0500

Hello, The code is from http://www.opencv.jp/sample/svm.html. I have tested the SVM in OpenCV 2.4.6.1, but there is an error as follow:

undefined reference to `CvSVM::predict(CvMat const*) const'
collect2: ld returned 1 exit status

and I have linked the project with libraries as follows:

-lopencv_core  -lopencv_imgproc  -lopencv_highgui -lopencv_legacy
-lopencv_nonfree -lopencv_optim -lopencv_ml

Then, I replace the "#include <ml.h>" with "#include <ml.hpp>", there are more than 2000 errors, some are as follows:

/include/opencv2/core/cvdef.h:219: conflicting declaration 'typedef int64_t int64'
/include/cxtypes.h:145: 'int64' has a previous declaration as 'typedef long long int int64'
and so on

Then, I still use the "#include <ml.h>", and I comment the line 71 "ret = svm.predict(&m)", then everything is OK!

Then, I change the line 71 "ret = svm.predict (&m);" into "ret = svm.predict (&m ,false);", and modify the ml.h, in line 492, I add one row, like this:

virtual float predict( const CvMat* _sample ) const;
virtual float predict( const CvMat* _sample, bool returnDFVal ) const;

Then, everything is OK!

I think the ml.h should add some more override functions, because I check the modules/ml/src/svm.cpp, there are no override function for "virtual float predict( const CvMat* _sample ) const;". Maybe this is the problem. Please Check it. Thanks.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2013-09-28 05:20:49 -0500

berak gravatar image

hey, no idea under which rock you found that sample, but it's using the 1.0 c-api, and you should not.

don't even bother trying to get it to run, it's outdated. just as an idea, how it would look in c++ :

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/ml/ml.hpp"
#include <time.h>

using namespace std;
using namespace cv;

void cross( Mat & img, float x, float y, const Scalar & color ) {
    line (img, Point(x - 2, y - 2), Point(x + 2, y + 2), color);
    line (img, Point(x + 2, y - 2), Point(x - 2, y + 2), color);
}

int main(int argc, char **argv)
{
    const int s = 1000;
    int size = 400;

    RNG rng(time (NULL));

    Mat_<float> pts(s,2); // our training data, s points with 2 dimensions (x,y)
    Mat_<int>   res(s,1); // our training labels, one label(id) for each point

    Mat img = Mat::zeros(size, size,CV_8UC3);  // data visualization

    for (int i = 0; i < s; i++) {
        pts(i,0) = rng.uniform(0.0f,float(size));
        pts(i,1) = rng.uniform(0.0f,float(size));
        if (pts(i,1) > 50 * cos (pts(i,0) * CV_PI / 100) + 200) {
            cross( img, pts(i,0), pts(i,1), Scalar(0,0,255) );
            res(i) = 1;
        } else {
            if (pts(i,0) > 200) {
                cross( img, pts(i,0), pts(i,1), Scalar(0,255,0) );
                res(i) = 2;
            } else {
                cross( img, pts(i,0), pts(i,1), Scalar(255,0,0) );
                res(i) = 3;
            }
        }
    }

    namedWindow("SVM", CV_WINDOW_AUTOSIZE);
    imshow("SVM", img);
    waitKey(0);

    pts /= size; // downscale to [0..1]

    // setup the svm    
    TermCriteria criteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
    SVMParams param( SVM::C_SVC, SVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria );

    SVM svm;
    svm.train(pts, res, Mat(), Mat(), param);

    // make a prediction for each point on the grid:
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            float a[] = { float(j)/size, float(i)/size };
            Mat m(1,2,CV_32F,a);
            float ret = svm.predict(m);
            switch ((int) ret) {
                case 1:  circle( img, Point(j,i), 1, Scalar(0,0,90) );  break;
                case 2:  circle( img, Point(j,i), 1, Scalar(0,90,0) );  break;
                case 3:  circle( img, Point(j,i), 1, Scalar(90,0,0) );  break;
            }
        }
    }

    // overlay the training points again
    pts *= size; // upscale again for drawing
    for (int i = 0; i < s; i++) {
        switch (res(i)) {
            case 1: cross( img, pts(i,0), pts(i,1), Scalar(0,0,255) );  break;
            case 2: cross( img, pts(i,0), pts(i,1), Scalar(0,255,0) );  break;
            case 3: cross( img, pts(i,0), pts(i,1), Scalar(255,0,0) );  break;
        }
    }

    // overlay the support vecs
    int sv_num = svm.get_support_vector_count();
    for (int i = 0; i < sv_num; i++) {
        const float * support = svm.get_support_vector(i);
        circle( img, Point( int(support[0]*size), int(support[1]*size) ), 5, Scalar(200,200,200) );
    }

    imshow("SVM", img);
    waitKey(0);

    return 0;
}
edit flag offensive delete link more

Comments

Thank you very much for so detail explanation. Yes, I have found that OpenCV 1.1 could work today. I think some deprecated functions should be removed from the include files. So developers could save time.

zszhong gravatar imagezszhong ( 2013-09-28 07:36:30 -0500 )edit
Login/Signup to Answer

Question Tools

Stats

Asked: 2013-09-27 19:18:15 -0500

Seen: 1,442 times

Last updated: Sep 28 '13