入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

C++ cin 多读取一个字节数据的问题

创建时间:2017-03-27 投稿人: 浏览次数:884

最近研究caffe,有一个cifar10的数据集http://www.cs.toronto.edu/~kriz/cifar.html, 但是下载之后只有一个bin文件,无法直观的查看其中的图片,于是我们就想写一个转换函数,将其中的图片数据提取出来。但是遇到了问题。

官网对bin格式的数据描述如下:

Binary version

The binary version contains the files data_batch_1.bin, data_batch_2.bin, …, data_batch_5.bin, as well as test_batch.bin. Each of these files is formatted as follows:

<1 x label><3072 x pixel>

<1 x label><3072 x pixel>

In other words, the first byte is the label of the first image, which is a number in the range 0-9. The next 3072 bytes are the values of the pixels of the image. The first 1024 bytes are the red channel values, the next 1024 the green, and the final 1024 the blue. The values are stored in row-major order, so the first 32 bytes are the red channel values of the first row of the image.

Each file contains 10000 such 3073-byte “rows” of images, although there is nothing delimiting the rows. Therefore each file should be exactly 30730000 bytes long.

我们的初始代码如下:
图像数据好像没啥多大问题,不过数据的标签弄错了

void ReadCifar10::LoadAndSaveBinFile(string name, string folder){
    char label;
    ifstream fin(name, ios::binary);

    for (int j = 0; j < 10000; j++){
        fin >> label;
        char buffer[3][1024] = { 0 };
        vector<Mat> channels;
        for (int i = 2; i >= 0; i--){
            fin.read(buffer[i], 1024);
            channels.emplace_back(Mat(32, 32, CV_8UC1, buffer[i]));
        }

        Mat src;
        merge(channels, src);       
        imwrite(folder + "\" + to_string(j) + ".jpg", src);

我们一开始怀疑是不是我们下载的数据集出现了什么问题,然而通过查看数据内容发现没有问题。接着我们试着在代码种加入一定的调试信息,我们发现读取第二幅图片数据的时候,跳过了标签项数据 09, 也就是说我们多读取了一个字节的数据
这里写图片描述
这里写图片描述
由此,我们知道了问题所在, 也就是 fin 读取数据的时候会多读取一个字节的数据,导致读取出现问题,采用read方式就可以进行避免了

代码如下:

void ReadCifar10::LoadAndSaveBinFile(string name, string folder){
    char label;
    ifstream fin(name, ios::binary);

    for (int j = 0; j < 10000; j++){
        fin.read(&label, 1);
        char buffer[3][1024] = { 0 };
        vector<Mat> channels;
        for (int i = 2; i >= 0; i--){
            fin.read(buffer[i], 1024);
            channels.emplace_back(Mat(32, 32, CV_8UC1, buffer[i]));
        }

        Mat src;
        merge(channels, src);       
        imwrite(folder + "\" + to_string(j) + ".jpg", src);
    }   
}

图片提取效果:
这里写图片描述

这个问题,其实在以前的编程过程种也遇到过,但是没怎么注意,今天特地记录一下,以免以后仍然遇到类似的问题,还是不清楚如何处理。

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。