ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

具体封装函数讲解read_num_class_data()、prepare_train_data()(OpenCV案例源码letter_recog.cpp解读)

2020-03-18 09:51:08  阅读:360  来源: 互联网

标签:recog Mat int 源码 samples data ptr responses


letter_recog.cpp的整体认识查阅RTrees、Boost、ANN_MLP、KNearest、NormalBayesClassifier、SVM,大写英文字母识别,三目运算符的妙用(OpenCV案例源码letter_recog.cpp解读)

letter-recognition.data,20000*17,前16000行用于训练,后4000行测试。

 

 

1、read_num_class_data()函数,把数据的第一列保存到标签集_responses,之后的16列保存到特征集_data。

用到了两个函数,说明如下:

fgets(str,n,fp);

从fp指向的文件中获取n-1个字符,并在最后加一个'\0'字符,共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个字符,超过filename中每行字符数即可
    char buf[M + 2];//buf的第一个元素用于存放标签,+2防止溢出

    Mat el_ptr(1, var_count, CV_32F);//用于存放特征集
    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 (int 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.\n";

    return true;
}

2、prepare_train_data()函数,从特征集data中选取前80%行,所有列作为训练集。下文中有int ntrain_samples = (int)(nsamples_all*0.8);

//特征集data中选取前80%行,所有列作为训练集。下文中有int ntrain_samples = (int)(nsamples_all*0.8);
static Ptr<TrainData> prepare_train_data(const Mat& data, const Mat& responses, int ntrain_samples)
{
    Mat sample_idx = Mat::zeros(1, data.rows, CV_8U);
    Mat train_samples = sample_idx.colRange(0, ntrain_samples);//80%的样本
    train_samples.setTo(Scalar::all(1));//操作train_samples就是操作sample_idx,浅拷贝。sample_idx中前80%变为1

    return TrainData::create(data, ROW_SAMPLE, responses,noArray(), sample_idx);//所有特征(列)参与训练,前80%样本(行)参与训练
}

3、训练终止条件

inline TermCriteria TC(int iters, double eps)
{
    return TermCriteria(TermCriteria::MAX_ITER + (eps > 0 ? TermCriteria::EPS : 0), iters, eps);
}

4、

标签:recog,Mat,int,源码,samples,data,ptr,responses
来源: https://www.cnblogs.com/xixixing/p/12515510.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有