opencv 手写选择题阅卷 (三)训练分类器

1,分类器选择:SVM

本来一开始用的KNN分类器,但这个分类器目前没有实现保存训练数据的功能,所以选择了SVN分类器;

2,样本图像的预处理和特征提取代码与识别代码中使用一样的代码.

3,训练时的输入数据主要为两个矩阵,一个矩阵保存所有样本的特征数据,每一行一个图像,另一个矩阵保存每个样本所属的类别,比如 1.0代表A,2.0代表B,0代表空白.

4,所有样本分别保存在5个文件夹中(一个是空白,四个字母ABCD),用批处理生成一个文本文件包括所有样本文件文件名和分类:

目前只使用了四个人书写的60个字母和几个空白样本,后期再增加更多人的更多样本,文本文件内容如下样式:

1 A\2016072316013018.png
1 A\2016072316013022.png
1 A\2016072316013026.png
2 B\2016072316010401.png
2 B\2016072316010405.png
2 B\2016072316010409.png

;//每个字符多个个图片

    FILE * pf = fopen(listname,"r");
    if (pf == NULL){
        printf("没有发现样本列表文件;\n");
        return;
    }
    ];
    ){
        , pf))
            break;
        )
            continue;
        n_img++;
    }

    HOGDescriptor *hog = , ), cvSize(, ), cvSize(, ), cvSize(, ), );
    int nw = hog->getDescriptorSize();
    CvMat * trainData = cvCreateMat(n_img, nw, CV_32FC1);
    CvMat * trainClasses = cvCreateMat(n_img, , CV_32FC1);

    //每个样本都要提取特征,写入到训练矩阵
    ] = "";
    strcpy(path, listname);
    int path_len = strlen(listname);
    ; i--){
        if (path[i] == '\\'){
            path[i+] = '\0';
            break;
        }
    }
    fseek(pf, , SEEK_SET);
    ;//训练数据中的第N个
    ){
        , pf))
            break;
        )
            continue;

        char * str_lable = line;
        char * str_imgname = NULL;
        int line_len = strlen(line);
        ; i < line_len; i++)
        {
            if (line[i] == ' '){
                line[i] == '\0';
                str_imgname = line + i + ;
                break;
            }
        }
        if (str_imgname == NULL)
            continue;

        ] = "";
        strcpy(img_name, path);
        strcat(img_name, str_imgname);
        img_name[strlen(img_name) - ] = '\0';

        IplImage* src = cvLoadImage(img_name, );
        if (src == NULL)
        {
            printf("打开样本图片出错:%s;\n", img_name);
            continue;
        }

        IplImage* train_img = cvCreateImage(cvSize(, ), , );
        preproc_img(src, train_img);

        vector<float> descriptors;//存放结果
        hog->compute(train_img, descriptors, Size(, ), Size(, )); //Hog特征计算
        ;
        for (vector<float>::iterator iter = descriptors.begin(); iter != descriptors.end(); iter++)
        {
            cvmSet(trainData, nItem, n, *iter);//存储HOG特征
            n++;
        }

        double val = strtod(str_lable, NULL);
        cvmSet(trainClasses, nItem, , val);

        cvReleaseImage(&src);
        cvReleaseImage(&train_img);

        nItem++;
    }
    if (nItem != n_img){
        printf("实际样本数据与列表中样本数据不同;\n");
    }
    fclose(pf);

    CvSVM svm;//新建一个SVM
    CvSVMParams param;//这里是SVM训练相关参数
    CvTermCriteria criteria;
    criteria = cvTermCriteria(CV_TERMCRIT_EPS, , FLT_EPSILON);
    param = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria);
    svm.train(trainData, trainClasses, NULL, NULL, param);//训练数据
    //保存训练好的分类器
    svm.save("HOG_SVM_DATA.xml");

    cvReleaseMat(&trainData);
    cvReleaseMat(&trainClasses);

}

opencv 手写选择题阅卷 (三)训练分类器的更多相关文章

  1. opencv 手写选择题阅卷 (二)字符识别

    opencv 手写选择题阅卷 (二)字符识别 选择题基本上只需要识别ABCD和空五个内容,理论上应该识别率比较高的,识别代码参考了网上搜索的代码,因为参考的网址比较多,现在也弄不清是参考何处的代码了, ...

  2. opencv 手写选择题阅卷 (四)Android端 手机应用开发

    opencv 手写选择题阅卷 (四)Android 手机应用开发 在PC端把代码调通以后开始开发Android 手机应用,因为主要功能代码为C++代码,所以需要通过NDK编译,JAVA通过JNI方式调 ...

  3. opencv 手写选择题阅卷 (一)表格设计与识别

    (一)答题表格设计与识别 实际设计好的表格如下图 为了图像精确,表格和四角的标记都是由程序生成的,文字和数据是后期排版软件添加上去的. 图中四角的四个黑方块主要用来定位表格,然后就可以切割出每个单元格 ...

  4. TensorFlow 入门之手写识别CNN 三

    TensorFlow 入门之手写识别CNN 三 MNIST 卷积神经网络 Fly 多层卷积网络 多层卷积网络的基本理论 构建一个多层卷积网络 权值初始化 卷积和池化 第一层卷积 第二层卷积 密集层连接 ...

  5. 利用opencv源代码和vs编程序训练分类器haartraining.cpp

    如需转载请注明本博网址:http://blog.csdn.net/ding977921830/article/details/47733363. 一  训练框架 训练人脸检測分类器须要三个步骤: (1 ...

  6. OpenCV手写数字字符识别(基于k近邻算法)

    摘要 本程序主要参照论文,<基于OpenCV的脱机手写字符识别技术>实现了,对于手写阿拉伯数字的识别工作.识别工作分为三大步骤:预处理,特征提取,分类识别.预处理过程主要找到图像的ROI部 ...

  7. 利用keras进行手写数字识别模型训练,并输出训练准确度

    from keras.datasets import mnist (train_images, train_labels), (test_images, test_labels) = mnist.lo ...

  8. keras实现mnist手写数字数据集的训练

    网络:两层卷积,两层全连接,一层softmax 代码: import numpy as np from keras.utils import to_categorical from keras imp ...

  9. MNIST手写数字数据库

    手写数字库很容易建立,但是总会很浪费时间.Google实验室的Corinna Cortes和纽约大学柯朗研究所的Yann LeCun建有一个手写数字数据库,训练库有60,000张手写数字图像,测试库有 ...

随机推荐

  1. Linux內核中常用的一些延時方法

    Linux內核中常用的一些延時方法 這些方法在以下路徑下定義:kernel/include/linux/delay.h #ifndef _LINUX_DELAY_H #define _LINUX_DE ...

  2. java源码部署

    环境:nginx+tomcat部署方式:源码部署源码目录 /chroot2/test/schedule 目录下面就是所有源码了tomcat 位置: /usr/local/tomcat/apache-t ...

  3. android141 360 安装软件管理java代码

    AppManagerActivity package com.itheima52.mobilesafe.activity; import android.app.Activity; import an ...

  4. grunt自动化工具

    Grunt和 Grunt 插件是通过 npm 安装并管理的,npm是 Node.js 的包管理器. 安装 CLI 首先,需要先将Grunt命令行(CLI)安装到全局环境中. npm install - ...

  5. pt-table-checksum 与pt-table-sync

    http://www.lai18.com/user/481193.html?id=481193&p=1 主从数据校验使用percona-toolkit工具集的以下两个工具(主库上使用): pt ...

  6. 高级I/O之STREAMS

    http://en.wikipedia.org/wiki/STREAMS STREAMS(流)是系统V提供的构造内核设备驱动程序和网络协议包的一种通用方法,对STREAMS进行讨论的目的是为了理解系统 ...

  7. 基于 Jenkins 快速搭建持续集成环境--转

    源地址:http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/ 持续集成是一种软件开发实践,对于提高软件开发效率并保障软件开发质量提供了理论基础 ...

  8. jQuery插件面向对象开发

    为什么要有面向对象的思维,因为如果不这样,你可能需要一个方法的时候就去定义一个function,当需要另外一个方法的时候,再去随便定义一个function,同样,需要一个变量的时候,毫无规则地定义一些 ...

  9. hdu 4628 动态规划

    思路:首先就是状态压缩,然后判断哪些状态是回文串.最后就是动态方程:dp[i]=min(dp[i],dp[j]+1).这个方程得前提条件是状态(j-i)为回文串. #include<iostre ...

  10. Nginx HTTP User_agent

    假设我这里有大量图像.CSS.javascript等静态文件,分别放在后端服务器  192.168.1.5 和 192.168.1.6上,那么我如何利用nginx的反向代理功能将不同的 http_us ...