您的位置:首页 > 编程语言 > C语言/C++

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

2017-03-27 10:45 781 查看

1. 前言

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

2. 问题描述

官网对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);


3. 分析问题

我们一开始怀疑是不是我们下载的数据集出现了什么问题,然而通过查看数据内容发现没有问题。接着我们试着在代码种加入一定的调试信息,我们发现读取第二幅图片数据的时候,跳过了标签项数据 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);
}
}


图片提取效果:



4. 小结

这个问题,其实在以前的编程过程种也遇到过,但是没怎么注意,今天特地记录一下,以免以后仍然遇到类似的问题,还是不清楚如何处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++