#include<iostream>
#include<fstream>
#include<string>
#include<map>
#include<vector>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define CIFAR10 //or #define CIFAR100
#ifdef CIFAR10
const int FRAME_SIZE = 3073;
#endif // CIFAR10
#ifdef CIFAR100
const int FRAME_SIZE = 3074;
#endif // CIFAR100
struct CifarImg
{
CifarImg() : coarse_label{0}, fine_label{0}, label{-1} { }
unsigned char coarse_label;
unsigned char fine_label;
char label;//just for cifar10
Mat img;
};
//extract label info from cifar img frame
//<1 x label><<1024bytes red channel pixel><1024bytes green><1024bytes blue>>
CifarImg cifar10_img_info (const char* cifar_img_frame);
//<1 x coarse label><1 x fine label><<1024bytes red channel><1024bytes green><1024bytes blue>>
CifarImg cifar100_img_info (const char* cifar_img_frame);
int main()
{
//使用cat data_batch_1.bin data_batch_2.bin data_batch_3.bin data_batch_4.bin data_batch_5.bin > data_train.bin 可以将cifar10中分散的数据合并,以便于处理
const string cifar_path (R"(C:\Users\HJiahu\Desktop\cifar-10-binary.tar\cifar-10-binary\cifar-10-batches-bin\test_batch.bin)");
const string imgs_dst_path (R"(C:\Users\HJiahu\Desktop\cifar-10-binary.tar\cifar-10-binary\cifar-10-batches-bin\test_imgs)");
ifstream cifar_file_h (cifar_path, ifstream::binary);
decltype (cifar100_img_info) *cifar_img_info;
#if defined(CIFAR10)
cifar_img_info = cifar10_img_info;
#elif defined(CIFAR100)
cifar_img_info = cifar100_img_info;
#else
cerr << "Please define Macro CIFAR10 or CIFAR100 in src." << endl;
getchar();
exit (1);
#endif
char frame_buf[FRAME_SIZE];
int cnt = 0;
while (true)
{
cnt = cnt + 1;
if (cnt % 1000 == 0) { cout << '.'; }
cifar_file_h.read (frame_buf, FRAME_SIZE);
//只有在尝试读取非文件内容(即文件最后一个字节之后内容)时eof()才会返回true
//所以这里每读一次判断一次是否成功
if (!cifar_file_h.good()) { break; }
auto info = cifar_img_info (frame_buf);
string img_name;
if (info.label != -1)
{
img_name = to_string (info.label) + "_" + to_string (cnt) + ".jpg";
}
else
{
img_name = to_string (info.coarse_label) + "_" \
+ to_string (info.fine_label) + "_" \
+ to_string (cnt) + ".jpg";
//cout << cnt << endl;
}
imwrite (imgs_dst_path + "\\" + img_name, info.img);
}
}
CifarImg cifar10_img_info (const char* cifar_img_frame)
{
CifarImg info;
info.label = cifar_img_frame[0];
Mat r_chl (32, 32, CV_8UC1, (char*) cifar_img_frame + 1);
Mat g_chl (32, 32, CV_8UC1, (char*) cifar_img_frame + 1 + 1024);
Mat b_chl (32, 32, CV_8UC1, (char*) cifar_img_frame + 1 + 1024 + 1024);
vector<Mat> splited_mat = {b_chl, g_chl, r_chl};
//merge (splited_mat, info.img)在windows下opencv3.1报错
merge(&splited_mat[0], 3, info.img);
return info;
}
CifarImg cifar100_img_info (const char* cifar_img_frame)
{
CifarImg info;
//info.label = cifar_img_frame[0];
info.coarse_label = cifar_img_frame[0];
info.fine_label = cifar_img_frame[1];
Mat r_chl (32, 32, CV_8UC1, (char*) cifar_img_frame + 2);
Mat g_chl (32, 32, CV_8UC1, (char*) cifar_img_frame + 2 + 1024);
Mat b_chl (32, 32, CV_8UC1, (char*) cifar_img_frame + 2 + 1024 + 1024);
vector<Mat> splited_mat = { b_chl, g_chl, r_chl };
merge (&splited_mat[0], 3, info.img);
return info;
}