2

我正在阅读以下问题:

如何在 C++ 中读取 MNIST 数据?

并且有一些用于读取 MNIST 数据库的 C++ 代码。尝试后我发现它工作正常,直到它开始读取数据的地方。

这是以下代码:

 for(int i=0;i<number_of_images;++i)
      {
        for(int r=0;r<n_rows;++r)
        {
            for(int c=0;c<n_cols;++c)
            {
                unsigned char temp=0;
                file.read((char*)&temp,sizeof(temp));
                //cout<<(int)temp<<" "; //printing the pixel in integer format

            }
        }
    }

我尝试打印出变量“temp”的整数值,但是我没有得到正确的像素数(它们都为零)。我不确定那里出了什么问题,每个像素占用一个字节空间,然后我将其转换为 int 并且它不起作用。为什么会这样?先感谢您

4

3 回答 3

5

我有同样的问题,前几个字节的数据很好,然后其余的都用 0 填充。事实证明,文件流在第一次遇到字节 0x01A 时失败了。对此的修复正在改变:

ifstream file ("data");

ifstream file ("data", std::ios::binary);
于 2013-05-23T02:19:11.067 回答
2

在使用 MNIST 数据集时,我遇到了与您相同的问题。我可以阅读标签,但训练和测试集的图像大多是伪造的;训练集几乎完全用 175 填充,测试集几乎完全用 0 填充(前 6 张图像除外)。重新启动并没有解决问题,我无法确定文件读取工作不正常的原因。

对于有同样问题的任何人,我建议改用位于http://cis.jhu.edu/~sachin/digit/digit.html的数据文件。数据已经按数字组织(不需要标签/图像关联),像素值数组一个接一个地简单编码。知道每个数组是 28x28 并且每个数字有 1000 张图像,您可以轻松编写代码来输入像素值的单个图像数组。

于 2012-11-29T00:59:26.087 回答
1

以下是读取 mnist 并将其转换为的完整代码cv Mat

uint32_t swap_endian(uint32_t val) {
    val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
    return (val << 16) | (val >> 16);
}

void read_mnist_cv(const char* image_filename, const char* label_filename){
    // Open files
    std::ifstream image_file(image_filename, std::ios::in | std::ios::binary);
    std::ifstream label_file(label_filename, std::ios::in | std::ios::binary);

    // Read the magic and the meta data
    uint32_t magic;
    uint32_t num_items;
    uint32_t num_labels;
    uint32_t rows;
    uint32_t cols;

    image_file.read(reinterpret_cast<char*>(&magic), 4);
    magic = swap_endian(magic);
    if(magic != 2051){
        cout<<"Incorrect image file magic: "<<magic<<endl;
        return;
    }

    label_file.read(reinterpret_cast<char*>(&magic), 4);
    magic = swap_endian(magic);
    if(magic != 2049){
        cout<<"Incorrect image file magic: "<<magic<<endl;
        return;
    }

    image_file.read(reinterpret_cast<char*>(&num_items), 4);
    num_items = swap_endian(num_items);
    label_file.read(reinterpret_cast<char*>(&num_labels), 4);
    num_labels = swap_endian(num_labels);
    if(num_items != num_labels){
        cout<<"image file nums should equal to label num"<<endl;
        return;
    }

    image_file.read(reinterpret_cast<char*>(&rows), 4);
    rows = swap_endian(rows);
    image_file.read(reinterpret_cast<char*>(&cols), 4);
    cols = swap_endian(cols);

    cout<<"image and label num is: "<<num_items<<endl;
    cout<<"image rows: "<<rows<<", cols: "<<cols<<endl;

    char label;
    char* pixels = new char[rows * cols];

    for (int item_id = 0; item_id < num_items; ++item_id) {
        // read image pixel
        image_file.read(pixels, rows * cols);
        // read label
        label_file.read(&label, 1);

        string sLabel = std::to_string(int(label));
        cout<<"lable is: "<<sLabel<<endl;
        // convert it to cv Mat, and show it
        cv::Mat image_tmp(rows,cols,CV_8UC1,pixels);
        // resize bigger for showing
        cv::resize(image_tmp, image_tmp, cv::Size(100, 100));
        cv::imshow(sLabel, image_tmp);
        cv::waitKey(0);
    }

    delete[] pixels;
}

用法:

string base_dir = "/home/xy/caffe-master/data/mnist/";
string img_path = base_dir + "train-images-idx3-ubyte";
string label_path = base_dir + "train-labels-idx1-ubyte";

read_mnist_cv(img_path.c_str(), label_path.c_str());

输出如下:

在此处输入图像描述

于 2018-09-19T12:56:39.417 回答