将自己数据转化为cifar10支持的lmdb

大家都知道,在caffe里面,要运行cifar10的例子就得先由cifar10的数据库。由于caffe为了提高运行效率,减少磁盘寻道时间等,统一了数据接口(lmdb,leveldb)。

首先,看一下cafferoot/data/cifar10(cafferoot指的是自己caffe安装的根目录)下面的get_cifar10.sh


可见其下载的是bin格式的图片,然后通过cafferoot/examples/cifar10/create_cifar10.sh将bin文件转化为lmdb格式。

那么这样的问题来了,由于,cifar10由官网提供了2进制的bin文件,如果我们想训练自己的模型呢?如果我们想加进自己的图片呢。所以,一个保持和官网cifar10同步的将传统的jpg、png等格式转为bin格式的程序应用而生。

 

进入正题

1cifar10bin数据格式

image 的大小为32*32flag0-9,共10类,使用的是cifar-10数据集

二进制数据格式为flag,R(1024),G(1024),B(1024),每个通道按行排列

2,读取cifar10bin文件,将bin文件中数据转化为图片并显示

void read_cifar_bin(string file_address,vector<Mat>& image,vector<int>& flag)
{	
	int width = 32, height = 32;//注意这个数值,根据自己样本的大小进行修改,重要的事情说三遍
	ifstream fin(file_address, ios::binary);
	while (!fin.eof())
	{
		char flag_tmp;
		unsigned char tmp;
		Mat image_tmp(width, height, CV_8UC3);
		fin.read((char *)&flag_tmp, sizeof(flag_tmp));
		
		for (int j = 2; j >=0; j--)
		{
			for (int r = 0; r < image_tmp.rows; r++)
			for (int c = 0; c < image_tmp.cols; c++)
			{
				fin.read((char *)&tmp, sizeof(tmp));
				image_tmp.at<Vec3b>(r, c)[j] = tmp;
			}
		}
		image.push_back(image_tmp);
		flag.push_back(flag_tmp);

	}

}

3,将自己的jpgpng等传统格式转化为cifar10支持的bin文件

void write_cifar_bin(string file_address, vector<string>& image_address, vector<int>& flag)
{

	ofstream fout(file_address, ios::binary);
	for (size_t i = 0; i < image_address.size(); i++)
	{
		Mat image_tmp = imread(image_address[i], 1);
		resize(image_tmp, image_tmp, Size(32, 32));

		
		int pix[1024];
		char flag_tmp = flag[i];
		fout.write((char *)&flag_tmp, sizeof(flag_tmp));

		for (int j = 2; j >= 0; j--)
		{
			for (int r = 0; r < image_tmp.rows; r++)
			for (int c = 0; c < image_tmp.cols; c++)
			{
				unsigned char tmp = image_tmp.at<Vec3b>(r, c)[j];
				fout.write((char *)&tmp, sizeof(tmp));
				
			}
		}

	}

}

4,将bin转为图片的测试,并用opencv显示

int main()
{
	string file_address = "data_batch_1.bin";
	vector<Mat> image;
	vector<int>flag;
	read_cifar_bin(file_address, image, flag);
	imshow("test", image[5000]);//随便需要显示的图像。可以跟改[]中数据进行验证
	waitKey();
	return 0;
}

5,将bin转为图片的测试,并保存为jpg,并且保存相应的flag

int main()
{
	string file_address = "data_batch_1.bin";
	vector<Mat> image;
	vector<int>flag;
	read_cifar_bin(file_address, image, flag);
	ofstream mydata_batch_1("mydata_batch_1.txt");
	for (int i = 0; i < image.size(); i++)
	{
	char buffer[50];
	char address[100] = ".\\data_batch_1\\";
	_itoa(i, buffer, 10);
	imwrite(strcat(address, strcat(buffer, ".jpg")), image[i]);
	mydata_batch_1 << address << buffer <<".jpg"<< " " << flag[i] << endl;
	cout << i << endl;
	waitKey(1);
	}	
	return 0;
}

6,将图像转为bin

int main()
{
	string file_address = "mydata_batch_1.bin";
	vector<string> image_address;
	vector<int> flag;

	ifstream finSample("mydata_batch_1.txt");
	char buf[100], buftmp[50], flagtmp[10];
	while (!finSample.eof())
	{
		finSample.getline(buf, sizeof(buf));
		sscanf(buf, "%s %s", buftmp, flagtmp);
		int tmp=atoi(flagtmp);
		image_address.push_back(buftmp);
		flag.push_back(tmp);

	}
	write_cifar_bin(file_address, image_address, flag);
	return 0;
}

7,实验测试

(1)【步骤4】将cifar10的data_batch_1.bin转化为图像的测试,从左到右依次为image[0],image[5000],image[9999](cifar10每个batch有10000个图像,所以是0-9999)


(2) 【步骤5】将cifar10的data_batch_1.bin转化为图像,并保存在jpg格式的测试。


(3)【步骤6】将第二步生成的jpg转化为bin文件, 程序运行后将生成mydata_batch_1.bin,可以看到和原始的data_batch_1.bin有着同样的大小。


那么到底这个和原始的一样不一样呢?我们还是使用步骤4的程序进行测试,同样的还是测试image[0],image[5000],image[9999],从下图可以看出和原始的bin的数据是一样的。

有了上面的2个转化程序,就可以转化自己的图像了,then let's make some noise!


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值