手写字符识别资源汇总


目前主流的手写数字字符数据集主要是MNIST、Semeion以及USPS

[MNIST]
该数据集包括60000个训练样本和10000个测试样本以及对应的labels,每个样本的大小是16*16,样本数据是0-255的值。
数据集的文件格式在其主页上有详细说明,样本数据以及标签的读取可参考[Handwritten Digit Classification](MATLAB)和[使用MNIST数据集] (C#)
[Semeion]
该数据集一共有1593个样本,样本大小为16*16,样本数据为0/1布尔值,该数据格式简单,容易读取。
[USPS]
该数据集包括4649个训练样本和4649个测试样本以及对应labels,每个样本大小是16*16,样本数据范围-1.0-1.0,数据集是mat类型,MATLAB可直接读取,准备把它的数据转存二进制文件,用C/C++读取。

下面给出MNIST训练数据集以及Semeion数据集C/C++ 读取方法

include <opencv2/core/core.hpp>

include <opencv2/highgui/highgui.hpp>

include <iostream>

include <stdio.h>

include <fstream>

using namespace cv;
using namespace std;

int loadSemeion(string filename)
{
    ifstream fp;
    fp.open(filename.c_str());
    if(!fp.is_open())
        return -1;
    
    vector<Mat> train_datas;
    vector<int> train_labels;
    int imgN = 0;
    while(imgN < 1593)
    {
        float bit;
        Mat im = Mat(16,16,CV_8U,Scalar(0));
        for (int i=0;i<256;i++)
        {
            fp >> bit;
            if(bit > 0)
            {
                int j = i/256;
                int k = i%256;
                im.at<uchar>(j,k)= 255;
            }
        }
        train_datas.push_back(im);
        if(imgN > 1590)
            cout <<" index: ";
        for (int i =0; i< 10;i++)
        {
            int index;
            fp >> index;
            if(imgN > 1590)
                cout<<index<<" ";
            if(index == 1)
            {
                train_labels.push_back(i);
                //cout << i <<endl;
            }
        }
        if(imgN > 1590)
            cout <<endl;
        imgN++;
        imshow("im",im);
        waitKey(10);
    }

    cout << imgN << endl;
    cout << train_labels.size() <<" "<<train_datas.size()<<endl;

    fp.close();
    return 0;
}

int loadMnist(string trdatafile,string trlabesfile, int trainNum)
{
    vector<vector<uchar>> train_datas;
    vector<int>              train_labels;

    FILE *trdatafp;
    trdatafp = fopen(trdatafile.c_str(),"r");

    if(!trdatafp)
    {
        cout << "Open database failed..."<<endl;
        return -1;
    }

    // obtain file size:
//  fseek (fp , 0 , SEEK_END);
//  long lSize = ftell (fp);
//  rewind (fp);
// 
//  cout << lSize << endl;
    //Read train datas
//      [offset] [type]          [value]          [description] 
//      0000     32 bit integer  0x00000803(2051) magic number 
//      0004     32 bit integer  60000            number of images 
//      0008     32 bit integer  28               number of rows 
//      0012     32 bit integer  28               number of columns 
//      0016     unsigned byte   ??               pixel 
//      0017     unsigned byte   ??               pixel 
//      ........ 
//      xxxx     unsigned byte   ??               pixel

    int imgNum = 60000 ;
    int imgW = 28,imgH = 28;
    
    train_datas.resize(trainNum);
    train_labels.resize(trainNum);

    vector<Mat> trainImgs;
    int dataLen = imgW*imgH;
    fseek (trdatafp ,16, SEEK_SET);
    uchar *buffer = (uchar*) malloc (sizeof(uchar)*imgNum*dataLen);
    if (buffer == NULL) 
    {
        fputs ("Memory error",stderr); 
        return -1;
    }

    fread(buffer,sizeof(uchar),imgNum*dataLen,trdatafp);
    
    for (int i=0; i< trainNum;i++)
    {
        train_datas[i].resize(dataLen);
        uchar *data = buffer + i*dataLen;
        for(int j=0;j<dataLen;j++)
            train_datas[i][j] = data[j];
    }
    fclose(trdatafp);
    free(buffer);
    
    //Read labels
    FILE *trlabelfp;
    trlabelfp = fopen(trlabesfile.c_str(),"r");

    if(!trlabelfp)
    {
        cout << "Open database failed..."<<endl;
        return -1;
    }

    buffer = (uchar *)malloc(imgNum);
    fseek(trlabelfp,8,SEEK_SET);
    if (buffer == NULL) 
    {
        fputs ("Memory error",stderr); 
        return -1;
    }
    fread(buffer,sizeof(uchar),imgNum,trlabelfp);

    Mat img = Mat(imgH,imgW,CV_8U,Scalar(0));
    for (int i=0; i< trainNum;i++)
    {
        train_labels[i] = (int)buffer[i];

        if(i%500 != 0)
            continue;

        cout<<i<<" "<<(int)buffer[i]<<endl;
        ////display
        for(int j=0; j<28;j++)
            for (int k=0; k<28; k++)
            {
                img.at<uchar>(j,k) = train_datas[i][j*28 +k];
            }
        imshow("disp",img);
        waitKey(0);
    }
    waitKey(0);
    fclose(trlabelfp);
    free(buffer);
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
       //Load semeion dataset
//  string filename = "../semeion/semeion.data";
//  loadSemeion(filename);

      //Load mnist dataset
    string trainimages = "../MNIST/train-images.idx3-ubyte";
    string trainlabels = "../MNIST/train-labels.idx1-ubyte";
    loadMnist(trainimages,trainlabels,50000);


    return 0;
}
已邀请:

xhhfly

赞同来自: July 18205170495


MNIST数据集python读取方法:
import numpy as np
import struct

def get_data(images_name, labels_name):
    # 解析图像数据
    f = open(images_name, 'rb')
    buf = f.read()
    f.close()
    
    index = 0
    magic, image_num, rows, cols = struct.unpack_from('>IIII', buf, index)
    index += struct.calcsize('>IIII')
    
    images = np.zeros((image_num, rows*cols))
    for i in np.arange(image_num):
        for j in np.arange(rows*cols):
            images[i,j] = int(struct.unpack_from('>B', buf, index)[0])
            index += struct.calcsize('>B')

    # 解析labels数据
    f = open(labels_name, 'rb')
    buf = f.read()
    f.close()
    
    index = 0
    magic, label_num = struct.unpack_from('>II', buf , index)
    index += struct.calcsize('>II')
    
    labels = np.zeros((label_num, 1))
    for i in np.arange(label_num):
        labels[i][0] = int(struct.unpack_from('>B', buf, index)[0])
        index += struct.calcsize('>B')
        
    return images, labels

要回复问题请先登录注册

返回顶部