First time here? Check out the FAQ!

Ask Your Question
0

svm predict function always return a large number

asked Nov 25 '15

nqthiep gravatar image

updated Nov 26 '15

Hi all,

I trying to implement a simple sample, the purpose is tranning and detect a number. Source as following:

Step 1: Initial data for tranning: I used a collect of images number for traning data,

    Mat vectorMatToMat(vector<Mat> list) {
        if (list.empty()) {
            return Mat();
        }
        int row = list.size();
        int col = list.at(0).rows * list.at(0).cols;
        Mat data(row, col, CV_32FC1);
        int i = 0;
        for (i = 0; i < row; i++) {
            Mat rowMat = list.at(i).reshape(1, 1);
            rowMat.copyTo(data.row(i));
        }
        return data;
    }
    Mat vectorIntToMat(vector<int> list) {
        int row = list.size();
        Mat data(row, 1, CV_32SC1, &list[0]);
        return data;
    }

    Mat dataMat = vectorMatToMat(listImageForTraining);
    Mat dataLabel = vectorIntToMat(listLabel);

Step 2: Init SVM:

Ptr<TrainData> trainData = TrainData::create(dataMat, ROW_SAMPLE, dataLabel);

Ptr<SVM> model = SVM::create();
model->setType(SVM::C_SVC);
model->setKernel(SVM::LINEAR);
model->setC(7);
model->setNu(SVM::NU_SVC);
model->setP(0);
model->setDegree(0);
model->setGamma(20);
model->setCoef0(0);
TermCriteria term(CV_TERMCRIT_ITER +CV_TERMCRIT_EPS, 1000, 1e-6);
model->setTermCriteria(term);
model->train(trainData);

Step 3: trying using SVM for predict:

    int i = 0;
    for (i = 0; i < 15; i++) {
        Mat check = dataMat.row(i);
        ostringstream oss;
        oss << i;
        imshow(oss.str(), check.reshape(1, 128));

        check = check.reshape(1, 1);
        int lable = model->predict(check);

        cout << "Result: " << lable << endl;
    }

Step 4: Result:

Result: -1237234688
Result: 159407376
Result: 159407376
Result: 167908848
Result: 1065353216
Result: 1065353216
Result: 1065353216
Result: 1065353216
Result: 1065353216
Result: 1065353216
Result: 1065353216
Result: 1065353216
Result: 1065353216
Result: 1065353216
Result: 1065353216

As we can see, my result are very large number, although my labels are numbers in 0 to 10. I can not understand why, i think i have a mistake when I init SVM model.

But i dont know how to fix this issue, If there is any idea, please help me.

Thanks & Best Regards,

Thiep

Preview: (hide)

Comments

  1. If you're using C_SVC with a linear kernel, the only parameter to set is C. Though that is not the problem, keeping it simple is always a good idea
  2. After training model, what do you do? Do you save your trained SVM and later load it or what? You have skipped that part. In fact, when you use int lable = svm.predict(check); I see two problems: 1) I don't know where/how the svm variable has been created/initialized and 2) that svm is not a pointer (because you're using . instead of ->), and since you're clearly using OpenCV 3.0, something is wrong there. Please, add the initialization part that is missing
LorenaGdL gravatar imageLorenaGdL (Nov 25 '15)edit

I can see that some results are 1065353216. These value could be 1.0f.

Check these posts:

http://stackoverflow.com/questions/24...

http://stackoverflow.com/questions/68...

albertofernandez gravatar imagealbertofernandez (Nov 25 '15)edit

1 answer

Sort by » oldest newest most voted
3

answered Nov 26 '15

berak gravatar image

updated Nov 26 '15

please replace your vectorIntToMat(listLabel) with a plain Mat(listLabel, true) .

(constructing a Mat with a raw data pointer from a local var is UB)

Preview: (hide)

Comments

@berak: what's the reason for the UB? I've seen that kind of pointer-construction before and I thought it was safe. In fact, now I wonder when and when not it is safe. What's the difference between that and the automatic Mat() conversion?

LorenaGdL gravatar imageLorenaGdL (Nov 26 '15)edit
2

@LorenaGdL , this construct is only safe, as long as original data pointer stays in scope. (no data copy is done, no refcounting, just a shallow copy of the pointer)

berak gravatar imageberak (Nov 26 '15)edit

@berak: thanks :). I thought data was copied as in other versions of the Mat constructor. It seems 3.0 docs better describe each of such constructors behaviours and parameters

LorenaGdL gravatar imageLorenaGdL (Nov 26 '15)edit
1

Thank all your the support. I tried modify as @berak suggest, and my issue solved. @berak: I can't understand. Could you explain for me about the different between your way with my way?

nqthiep gravatar imagenqthiep (Nov 26 '15)edit

@nqthiep, Mat data(row, 1, CV_32SC1, &list[0]); copies only the address of the 1st element, not the content of the vector. you also passed a copy of the vector to your function, so once you return from vectorIntToMat, this copy will get deleted, and your labelsMat is invalid, when you want to train the svm

berak gravatar imageberak (Nov 27 '15)edit

some reorganizing to have an answer@nqthiep can you accept this one so topic looks solved?

StevenPuttemans gravatar imageStevenPuttemans (Nov 27 '15)edit

@berak Thank you so much for your explained. I understood. So, I'd like to solved this ticket.

nqthiep gravatar imagenqthiep (Nov 29 '15)edit

@StevenPuttemans: I dont know how to solve this ticket. Please point me.

nqthiep gravatar imagenqthiep (Nov 29 '15)edit
1

it's the little hook under the answer, and i'v already done that, ok ?

berak gravatar imageberak (Nov 29 '15)edit

Yes, Thank you :)

nqthiep gravatar imagenqthiep (Dec 1 '15)edit

Question Tools

2 followers

Stats

Asked: Nov 25 '15

Seen: 1,654 times

Last updated: Nov 26 '15