Why SVM->predict(Mat) returns very large value that is greater than number of class?

I start learning OpenCV and MFC, and my project is License Plate Recognition. However, there is a problem: SVM->predict(Mat) returns weird values and I don’t know why.

This is my code:

#include "TrainSVM.h"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
#include <iostream>

using namespace cv::ml;
using namespace std;
using namespace cv;

int TrainSVM::count_pixel(Mat img, bool black_pixel = 1)
{
    int black = 0, white = 0;
    for (int i = 0; i < img.rows; ++i)
        for (int j = 0; j < img.cols; ++j)
        {
            if (img.at<uchar>(i, j) == 0)
                ++black;
            else
                ++white;
        }
    return (black_pixel ? black : white);
}

vector<float> TrainSVM::calculate_feature(Mat src)
{
    Mat img = src;
    threshold(img, img, 100, 255, THRESH_BINARY);

    vector<float> r;
    resize(img, img, Size(20, 20));

    int h = img.rows / 4;
    int w = img.cols / 4;
    int S = count_pixel(img);
    int T = img.cols * img.rows;
    for (int i = 0; i < img.rows; i += h)
    {
        for (int j = 0; j < img.cols; j += w)
        {
            Mat cell = img(Rect(i, j, h, w));
            int s = count_pixel(cell);
            float f = (float)s / S;
            r.push_back(f);
        }
    }

    for (int i = 0; i < 16; i += 4)
    {
        float f = r[i] + r[i + 1] + r[i + 2] + r[i + 3];
        r.push_back(f);
    }

    for (int i = 0; i < 4; ++i)
    {
        float f = r[i] + r[i + 4] + r[i + 8] + r[i + 12];
        r.push_back(f);
    }
    r.push_back(r[0] + r[5] + r[10] + r[15]);
    r.push_back(r[3] + r[6] + r[9] + r[12]);
    r.push_back(r[7] + r[10] + r[13] + r[16]);
    r.push_back(r[23] + r[24] + r[25] + r[26]);
    r.push_back(r[2] + r[7] + r[12] + r[17]);
    r.push_back(r[9] + r[11] + r[13] + r[15]);
    r.push_back(r[10] + r[15] + r[20] + r[25]);
    r.push_back(r[14] + r[16] + r[18] + r[20]);

    return r; // 32 features
}

char TrainSVM::char_recog(Mat img_character)
{
    char c = '*';
    if (img_character.empty())
        return c;

    vector<float> feature = this->calculate_feature(img_character);
    Mat m = Mat(1, number_of_feature, CV_32F);

    for (size_t i = 0; i < feature.size(); ++i)
        m.at<float>(0, i) = feature[i];

    float r = svm->predict(m);
    int ri = (int)r;
    if (ri >= 0 && ri <= 9)
        c = char(ri + 48);
    if (ri >= 10 && ri < 18)
        c = char(ri + 55);
    if (ri >= 18 && ri < 22)
        c = char(ri + 55 + 2);
    if (ri == 22)
        c = 'P';
    if (ri == 23)
        c = 'S';
    if (ri >= 24 && ri < 27)
        c = char(ri + 60);
    if (ri >= 27 && ri < 30)
        c = char(ri + 61);

    return c;
}


void TrainSVM::train_model()
{
    svm->setC(16);
    svm->setGamma(0.5);
    svm->setType(SVM::C_SVC);
    svm->setKernel(SVM::RBF);
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));

    Mat data = Mat(number_of_sample * number_of_class, number_of_feature, CV_32F);
    Mat label = Mat(number_of_sample * number_of_class, 1, CV_32S);
    int index = 0;

    vector<string> folders = list_folder("D:\\Image Processing\\Data");
    for (size_t i = 0; i < folders.size(); ++i)
    {
        vector<string> files = list_file(folders.at(i));
        string folder_path = folders.at(i);
        string label_folder = folder_path.substr(folder_path.length() - 1);
        for (size_t j = 0; j < files.size(); ++j)
        {
            Mat src = imread(files.at(j));
            if (src.empty())
                continue;
            vector<float> feature = calculate_feature(src);
            if (feature.size() < number_of_feature)
                continue;

            for (size_t t = 0; t < feature.size(); ++t)
                data.at<float>(index, t) = feature.at(t);
            label.at<float>(index, 0) = int(i);
            ++index;
        }
    }

    Ptr<TrainData> trainData = TrainData::create(data, ROW_SAMPLE, label);
    this->svm->trainAuto(trainData);
}

I run train_model()before char_reg() but char_reg() always returns large value.
Here are some values that out of number of class:

1.08423e+09
1.09157e+09
1.07374e+09
1.08423e+09
1.08423e+09
1.10258e+09
1.08423e+09
1.09157e+09
1.08842e+09

I have tried to using KNearest:

Mat res;
this->knn->findNearest(m, 1, res);
outFile << res.at<int>(0, 0);

And it returned this:

1.31709e+09
1.31717e+09
1.31701e+09
1.31709e+09
1.31709e+09
1.31709e+09
1.31709e+09
1.31709e+09
1.31713e+09

I have checked Mat data, label and sample. Of course, there is no error.

please show your prediction code.

how can char_reg() even return a float value ? or even one larger than 255 ?

then, WTFloat ?

then, what’s the motivation for your ‘features’ ? it does not make much sense to me, please explain !