• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

深度学习3番外篇—mnist数据集格式及转换

人工智能 _寒潭雁影 1969次浏览 0个评论

mnist是在图像机器学习占据“Hello World”地位的库。下载地址如下:http://yann.lecun.com/exdb/mnist/ train-images-idx3-ubyte(训练集数据,存放训练图像的集合) train-labels-idx1-ubyte(训练集标签,存放训练图像属于1~9中的哪一个) t10k-images-idx3-ubyte(测试集数据,存放测试图像的集合) t10k-labels-idx1-ubyte(测试集标签,存放测试图像属于1~9中的哪一个) 可见其是两类文件,数据和标签。 首先数据文件的存放格式如下: 第0~3字节:为魔数,其实就是校验位,告诉我们这个文件就是数据文件 第4~7字节:图像个数,告诉我们这个数据集里面存放了多少张图像 第8~11字节:每个图像有多少行 第12~15字节:每个图像有多少列 后面的数据是按先列后行的方式存储的图像数据,一张图像的占用空间为:(行×列)个字节 有了上面这些信息,就可以从数据文件中解析出图像了,代码如下:    

#include <opencv2/opencv.hpp>    
using namespace cv;
void main()
{
	char savepath[30];//图像存储路径
	uchar readbuf[4];//信息数据读取空间
	FILE *f;
	fopen_s(&f, "train-images.idx3-ubyte","rb");
	fread_s(readbuf, 4, 1, 4, f);//读取魔数,即文件标志位
	fread_s(readbuf, 4, 1, 4, f);//读取数据集图像个数
	int numOfImg = (readbuf[0] << 24)+ (readbuf[1] << 16)+(readbuf[2]<<8)+ readbuf[3];//图像个数
	fread_s(readbuf, 4, 1, 4, f);//读取数据集图像行数
	int imgheight= (readbuf[0] << 24) + (readbuf[1] << 16) + (readbuf[2] << 8) + readbuf[3];//图像行数
	fread_s(readbuf, 4, 1, 4, f);//读取数据集图像列数
	int imgwidth = (readbuf[0] << 24) + (readbuf[1] << 16) + (readbuf[2] << 8) + readbuf[3];//图像列数
	int imgdatalen = imgheight*imgwidth;//图像数据长度
	Mat img(imgheight, imgwidth, CV_8UC1);
	for (int i = 0; i < numOfImg; i++)
	{
		sprintf_s(savepath, 30,"train-images\\%5d.png", i + 1);
		fread_s(img.data, imgdatalen, 1, imgdatalen, f);//读取数据集图像列数
		imwrite(savepath, img);
		if ((i+1)%100==0)
		{
			printf("%5d.png\n", i + 1);
		}
	}
	img.release();
	fclose(f);
}

    因为图像是用来训练测试的,因此光有图像数据本身不够,还要知道图像上面的字符到底是个啥,这也就是标签文件的作用。其格式如下: 第0~3字节:为魔数,也就是校验位,告诉我们这个文件就是标签文件 第4~7字节:标签个数,告诉我们这个数据集里面存放了多少个图像的标签 后面一个字节代表一个标签(0~9中的一个数) 有了上面这些信息,就可以从标签文件中解析出图像标签了,代码如下:  

#include <opencv2/opencv.hpp>    
using namespace cv;
void main()
{
	uchar readbuf[4];//信息数据读取空间
	FILE *f;
	fopen_s(&f, "train-labels.idx1-ubyte", "rb");
	fread_s(readbuf, 4, 1, 4, f);//读取魔数,即文件标志位
	fread_s(readbuf, 4, 1, 4, f);//读取数据集图像个数
	int numOfImg = (readbuf[0] << 24) + (readbuf[1] << 16) + (readbuf[2] << 8) + readbuf[3];//图像个数
	for (int i = 1; i <= numOfImg; i++)
	{
		fread_s(readbuf, 1, 1, 1, f);//读取数据集图像列数
		printf("%d    ", readbuf[0]);
	}
	fclose(f);
}

  对比解析出来的图像和标签,很容易发现他们是一一对应的,这也是其意义所在。 为了训练方便,我们一般用一个数组将标签和图像数据存在一起,代码如下:  

#include "stdafx.h"
#include <opencv2/opencv.hpp>    
using namespace cv;

class numImg
{
public:
	Mat img;
	uchar tag;
};

void main()
{
	/**********************************/
	/***********读取图片数据***********/
	/**********************************/
	char savepath[30];//图像存储路径
	uchar readbuf[4];//信息数据读取空间
	FILE *f;
	fopen_s(&f, "train-images.idx3-ubyte", "rb");
	fread_s(readbuf, 4, 1, 4, f);//读取魔数,即文件标志位
	fread_s(readbuf, 4, 1, 4, f);//读取数据集图像个数
	int sumOfImg = (readbuf[0] << 24) + (readbuf[1] << 16) + (readbuf[2] << 8) + readbuf[3];//图像个数
	fread_s(readbuf, 4, 1, 4, f);//读取数据集图像行数
	int imgheight = (readbuf[0] << 24) + (readbuf[1] << 16) + (readbuf[2] << 8) + readbuf[3];//图像行数
	fread_s(readbuf, 4, 1, 4, f);//读取数据集图像列数
	int imgwidth = (readbuf[0] << 24) + (readbuf[1] << 16) + (readbuf[2] << 8) + readbuf[3];//图像列数
	int imgdatalen = imgheight * imgwidth;//图像数据长度
	numImg* mNumImg=new	numImg[sumOfImg];
	for (int i = 0; i < sumOfImg; i++)
	{
		mNumImg[i].img = Mat(imgheight, imgwidth, CV_8UC1);
		fread_s(mNumImg[i].img.data, imgdatalen, 1, imgdatalen, f);//读取数据集图像列数
	}
	fclose(f);
	/**********************************/
	/***********读取标签数据***********/
	/**********************************/
	fopen_s(&f, "train-labels.idx1-ubyte", "rb");
	fread_s(readbuf, 4, 1, 4, f);//读取魔数,即文件标志位
	fread_s(readbuf, 4, 1, 4, f);//读取数据集图像个数
	sumOfImg = (readbuf[0] << 24) + (readbuf[1] << 16) + (readbuf[2] << 8) + readbuf[3];//图像个数
	for (int i = 0; i <= sumOfImg; i++)
	{
		fread_s(&mNumImg[i].tag, 1, 1, 1, f);//读取数据集图像列数
		//printf("%d    ", mNumImg[i].tag);
		//imshow("", mNumImg[i].img);
		//waitKey(3000);
	}
	fclose(f);

	//mNumImg 中存着图像和对应的标签,用完记得释放掉内存
}

  此外,因为python最近相当火,在这里也放上python读取mnist的代码  

import numpy as np
import struct

def loadImageSet(filename):
	print ("load image set",filename)
	binfile= open(filename, 'rb')
	buffers = binfile.read()
	head = struct.unpack_from('>IIII' , buffers ,0)
	print ("head,",head)
	offset = struct.calcsize('>IIII')
	imgNum = head[1]
	width = head[2]
	height = head[3]
	#[60000]*28*28
	bits = imgNum * width * height
	bitsString = '>' + str(bits) + 'B' #读取定长数据段,即字符集图片总和
	imgs = struct.unpack_from(bitsString,buffers,offset)
	binfile.close()
	imgs = np.reshape(imgs,[imgNum,1,width*height])#将字符集图片分隔为单张图片
	print ("load imgs finished")
	return imgs

def loadLabelSet(filename):
	print ("load label set",filename)
	binfile = open(filename, 'rb')
	buffers = binfile.read()
	head = struct.unpack_from('>II' , buffers ,0)
	print ("head,",head)
	imgNum=head[1]
	offset = struct.calcsize('>II')
	numString = '>'+str(imgNum)+"B"
	labels = struct.unpack_from(numString , buffers , offset)
	binfile.close()
	labels = np.reshape(labels,[imgNum,1])
	print ('load label finished')
	return labels

 


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明深度学习3番外篇—mnist数据集格式及转换
喜欢 (0)

您必须 登录 才能发表评论!

加载中……