TrainData类型数据集(OpenCV案例源码letter_recog.cpp解读2)

Posted xixixing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TrainData类型数据集(OpenCV案例源码letter_recog.cpp解读2)相关的知识,希望对你有一定的参考价值。

letter_recog.cpp是ml.hpp的最佳案例,可以解读出样本集、机器学习的内容,所以写了两篇博客。

ml.hpp的整体理解,请拜读大神的文章,多读几遍。

【样本集】

1、文件的读取、保存,推荐用load()、save(),而不是read()、write()。

2、样本集有data(数据集)、responses(标签集)两部分,data必须是32FC1(32位浮点单通道)类型。

【TrainData类型的解释】

解释针对分类问题,而不是回归拟合。samples样本集中每1行为1个样本,每1列为1个特征。
Ptr<TrainData> create(InputArray samples, int layout, InputArray responses, InputArray varIdx=noArray(), InputArray sampleIdx=noArray(),InputArray sampleWeights=noArray(), InputArray varType=noArray());
  samples——样本集(特征变量组成的集合),必须是32FC1(32位浮点单通道)类型
  layout——样本布局,ROW_SAMPLE = 0,COL_SAMPLE = 1,此处只用前者
  responses——类别标签,必须是CV_32S类型(即int型)。一维向量,与每一行样本对应。
  varIdx——参与训练的特征(默认都参与),元素为0、非0的一维向量(行列都可),大小为特征数(列数)。1对应的样本参与训练(非0有效),格式用CV_8U即可
  sampleIdx——参与训练的样本(默认都参与),同上,大小为总样本数(行数)
  sampleWeights——样本权重,忽略不用
  varType——特征变量的类型,忽略不用

【其他函数讲解】

fgets(str,n,fp);

从fp指向的文件中获取n-1个字符,并在最后加一个‘‘字符,共n个字符,放到字符数组str中。
如果在读完n-1个字符之前就遇到了换行符或eof,读入结束。
fgets函数返回值为str的首地址。

float a;
int b;
sscanf(ptr, "%f%n", &a, ,&b);//ptr指向的内容中获取浮点型格式的数据保存到a中(%f的作用),此%n所在位置(在当前浮点型之后1位)之前的字符个数保存到b中(%n的作用)

// 把既有标签又有特征的集合,拆分为标签集_responses、特征集_data,var_count是特征数(_data的列数)
static bool read_num_class_data(const string& filename, int var_count,Mat* _data, Mat* _responses)
{
    const int M = 1024;//每行最多读取1024个字符
    char buf[M + 2];//buf的第一个元素用于存放标签

    Mat el_ptr(1, var_count, CV_32F);//用于存放特征集
    int i;
    vector<int> responses;//用于存放标签,push_back buf的第一个元素

    _data->release();
    _responses->release();

    FILE* f = fopen(filename.c_str(), "rt");//r只读,t文本文件(可省略,默认t)
    if (!f)
    {
        cout << "Could not read the database " << filename << endl;
        return false;
    }

    for (;;)
    {
        char* ptr;
        if (!fgets(buf, M, f) )//此处每次读一行,因为每行不够1024个字符,遇到换行符停止读取。
            break;//直到最后一行
        responses.push_back((int)buf[0]);//每行第1个元素放入responses中(标签)
        ptr = buf + 2;//ptr指向第一个逗号之后的数据,即第一个样本的第一个特征值
        for (i = 0; i < var_count; i++)//遍历一行中的每个元素
        {
            int n = 0;
            sscanf(ptr, "%f%n", &el_ptr.at<float>(i), &n);//把一行中的浮点数存放到el_ptr一维行向量中
            ptr += n + 1;//跳过逗号
        }
        _data->push_back(el_ptr);//存到特征集_data,_data指向一片Mat空间
    }
    fclose(f);
    Mat(responses).copyTo(*_responses);//保存到_responses指向的Mat空间

    cout << "The database " << filename << " is loaded.
";

    return true;
}

 

以上是关于TrainData类型数据集(OpenCV案例源码letter_recog.cpp解读2)的主要内容,如果未能解决你的问题,请参考以下文章

基于SGDASGD算法的SVM分类器(OpenCV案例源码train_svmsgd.cpp解读)

knn-matlab实现

HOG+SVM(OpenCV案例源码train_HOG.cpp解读)

OpenCV C++案例实战十《车牌号识别》

Canny,先Scharr得梯度再Canny,三通道黑色背景展示结果(OpenCV案例源码edge.cpp)

OpenCV:Scalar数据类型理解